ref: simplify node recursion functions, do not fetch both children at once if only one is used

This commit is contained in:
Alibek Omarov
2026-04-06 08:16:10 +05:00
parent 434e508186
commit e8ae48fd3d
8 changed files with 54 additions and 105 deletions

View File

@@ -612,9 +612,9 @@ static inline mnode_t *node_child( const mnode_t *n, int side, const model_t *mo
} }
} }
return n->children_[side]; return n->children_[side ? 1 : 0];
#else #else
return n->children_[side]; return n->children_[side ? 1 : 0];
#endif #endif
} }

View File

@@ -697,11 +697,8 @@ static void R_DecalNodeSurfaces( model_t *model, mnode_t *node, decalinfo_t *dec
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static void R_DecalNode( model_t *model, mnode_t *node, decalinfo_t *decalinfo ) static void R_DecalNode( model_t *model, mnode_t *node, decalinfo_t *decalinfo )
{ {
mplane_t *splitplane; mplane_t *splitplane;
float dist; float dist;
mnode_t *children[2];
Assert( node != NULL );
if( node->contents < 0 ) if( node->contents < 0 )
{ {
@@ -711,31 +708,22 @@ static void R_DecalNode( model_t *model, mnode_t *node, decalinfo_t *decalinfo )
splitplane = node->plane; splitplane = node->plane;
dist = DotProduct( decalinfo->m_Position, splitplane->normal ) - splitplane->dist; dist = DotProduct( decalinfo->m_Position, splitplane->normal ) - splitplane->dist;
node_children( children, node, model );
// This is arbitrarily set to 10 right now. In an ideal world we'd have the
// exact surface but we don't so, this tells me which planes are "sort of
// close" to the gunshot -- the gunshot is actually 4 units in front of the
// wall (see dlls\weapons.cpp). We also need to check to see if the decal
// actually intersects the texture space of the surface, as this method tags
// parallel surfaces in the same node always.
// JAY: This still tags faces that aren't correct at edges because we don't
// have a surface normal
if( dist > decalinfo->m_Size ) if( dist > decalinfo->m_Size )
{ {
R_DecalNode( model, children[0], decalinfo ); R_DecalNode( model, node_child( node, 0, model ), decalinfo );
} }
else if( dist < -decalinfo->m_Size ) else if( dist < -decalinfo->m_Size )
{ {
R_DecalNode( model, children[1], decalinfo ); R_DecalNode( model, node_child( node, 1, model ), decalinfo );
} }
else else
{ {
if( dist < DECAL_DISTANCE && dist > -DECAL_DISTANCE ) if( dist < DECAL_DISTANCE && dist > -DECAL_DISTANCE )
R_DecalNodeSurfaces( model, node, decalinfo ); R_DecalNodeSurfaces( model, node, decalinfo );
R_DecalNode( model, children[0], decalinfo ); R_DecalNode( model, node_child( node, 0, model ), decalinfo );
R_DecalNode( model, children[1], decalinfo ); R_DecalNode( model, node_child( node, 1, model ), decalinfo );
} }
} }

View File

@@ -105,7 +105,6 @@ void R_MarkLights( const dlight_t *light, int bit, const mnode_t *node )
const float maxdist = light->radius * light->radius; const float maxdist = light->radius * light->radius;
float dist; float dist;
int i; int i;
mnode_t *children[2];
int firstsurface, numsurfaces; int firstsurface, numsurfaces;
start: start:
@@ -115,17 +114,15 @@ start:
dist = PlaneDiff( light->origin, node->plane ); dist = PlaneDiff( light->origin, node->plane );
node_children( children, node, RI.currentmodel );
if( dist > virtual_radius ) if( dist > virtual_radius )
{ {
node = children[0]; node = node_child( node, 0, RI.currentmodel );
goto start; goto start;
} }
if( dist < -virtual_radius ) if( dist < -virtual_radius )
{ {
node = children[1]; node = node_child( node, 1, RI.currentmodel );
goto start; goto start;
} }
@@ -171,8 +168,8 @@ start:
else surf->dlightbits |= bit; else surf->dlightbits |= bit;
} }
R_MarkLights( light, bit, children[0] ); R_MarkLights( light, bit, node_child( node, 0, RI.currentmodel ));
R_MarkLights( light, bit, children[1] ); R_MarkLights( light, bit, node_child( node, 1, RI.currentmodel ));
} }
/* /*
@@ -236,7 +233,6 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
mtexinfo_t *tex; mtexinfo_t *tex;
matrix3x4 tbn; matrix3x4 tbn;
vec3_t mid; vec3_t mid;
mnode_t *children[2];
int firstsurface, numsurfaces; int firstsurface, numsurfaces;
// didn't hit anything // didn't hit anything
@@ -246,7 +242,6 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
return false; return false;
} }
node_children( children, node, model );
firstsurface = node_firstsurface( node, model ); firstsurface = node_firstsurface( node, model );
numsurfaces = node_numsurfaces( node, model ); numsurfaces = node_numsurfaces( node, model );
@@ -256,7 +251,7 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
side = front < 0; side = front < 0;
if(( back < 0 ) == side ) if(( back < 0 ) == side )
return R_RecursiveLightPoint( model, children[side], p1f, p2f, cv, start, end ); return R_RecursiveLightPoint( model, node_child( node, side, model ), p1f, p2f, cv, start, end );
frac = front / ( front - back ); frac = front / ( front - back );
@@ -264,7 +259,7 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
midf = p1f + ( p2f - p1f ) * frac; midf = p1f + ( p2f - p1f ) * frac;
// co down front side // co down front side
if( R_RecursiveLightPoint( model, children[side], p1f, midf, cv, start, mid )) if( R_RecursiveLightPoint( model, node_child( node, side, model ), p1f, midf, cv, start, mid ))
return true; // hit something return true; // hit something
if(( back < 0 ) == side ) if(( back < 0 ) == side )
@@ -366,7 +361,7 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
} }
// go down back side // go down back side
return R_RecursiveLightPoint( model, children[!side], midf, p2f, cv, mid, end ); return R_RecursiveLightPoint( model, node_child( node, !side, model ), midf, p2f, cv, mid, end );
} }
/* /*

View File

@@ -617,7 +617,6 @@ watertexture to grab fog values from it
static gl_texture_t *R_RecursiveFindWaterTexture( const mnode_t *node, const mnode_t *ignore, qboolean down ) static gl_texture_t *R_RecursiveFindWaterTexture( const mnode_t *node, const mnode_t *ignore, qboolean down )
{ {
gl_texture_t *tex = NULL; gl_texture_t *tex = NULL;
mnode_t *children[2];
// assure the initial node is not null // assure the initial node is not null
// we could check it here, but we would rather check it // we could check it here, but we would rather check it
@@ -655,18 +654,20 @@ static gl_texture_t *R_RecursiveFindWaterTexture( const mnode_t *node, const mno
// this is a regular node // this is a regular node
// traverse children // traverse children
node_children( children, node, WORLDMODEL ); mnode_t *child = node_child( node, 0, WORLDMODEL );
if( children[0] && ( children[0] != ignore )) if( child && ( child != ignore ))
{ {
tex = R_RecursiveFindWaterTexture( children[0], node, true ); tex = R_RecursiveFindWaterTexture( child, node, true );
if( tex ) return tex; if( tex ) return tex;
} }
if( children[1] && ( children[1] != ignore )) child = node_child( node, 1, WORLDMODEL );
if( child && ( child != ignore ))
{ {
tex = R_RecursiveFindWaterTexture( children[1], node, true ); tex = R_RecursiveFindWaterTexture( child, node, true );
if( tex ) return tex; if( tex ) return tex;
} }
// for down recursion, return immediately // for down recursion, return immediately

View File

@@ -3403,14 +3403,6 @@ R_RecursiveWorldNode
*/ */
static void R_RecursiveWorldNode( mnode_t *node, uint clipflags ) static void R_RecursiveWorldNode( mnode_t *node, uint clipflags )
{ {
int i, clipped;
msurface_t *surf, **mark;
mleaf_t *pleaf;
int c, side;
float dot;
mnode_t *children[2];
int numsurfaces, firstsurface;
loc0: loc0:
if( node->contents == CONTENTS_SOLID ) if( node->contents == CONTENTS_SOLID )
return; // hit a solid leaf return; // hit a solid leaf
@@ -3420,14 +3412,14 @@ loc0:
if( clipflags && !r_nocull.value ) if( clipflags && !r_nocull.value )
{ {
for( i = 0; i < 6; i++ ) for( int i = 0; i < 6; i++ )
{ {
const mplane_t *p = &RI.frustum.planes[i]; const mplane_t *p = &RI.frustum.planes[i];
if( !FBitSet( clipflags, BIT( i ))) if( !FBitSet( clipflags, BIT( i )))
continue; continue;
clipped = BOX_ON_PLANE_SIDE( node->minmaxs, node->minmaxs + 3, p ); int clipped = BOX_ON_PLANE_SIDE( node->minmaxs, node->minmaxs + 3, p );
if( clipped == 2 ) return; if( clipped == 2 ) return;
if( clipped == 1 ) ClearBits( clipflags, BIT( i )); if( clipped == 1 ) ClearBits( clipflags, BIT( i ));
} }
@@ -3436,19 +3428,11 @@ loc0:
// if a leaf node, draw stuff // if a leaf node, draw stuff
if( node->contents < 0 ) if( node->contents < 0 )
{ {
pleaf = (mleaf_t *)node; mleaf_t *pleaf = (mleaf_t *)node;
msurface_t **mark = pleaf->firstmarksurface;
mark = pleaf->firstmarksurface; for( int i = 0; i < pleaf->nummarksurfaces; i++ )
c = pleaf->nummarksurfaces; mark[i]->visframe = tr.framecount;
if( c )
{
do
{
(*mark)->visframe = tr.framecount;
mark++;
} while( --c );
}
// deal with model fragments in this leaf // deal with model fragments in this leaf
if( pleaf->efrags ) if( pleaf->efrags )
@@ -3461,19 +3445,20 @@ loc0:
// node is just a decision point, so go down the apropriate sides // node is just a decision point, so go down the apropriate sides
// find which side of the node we are on // find which side of the node we are on
dot = PlaneDiff( tr.modelorg, node->plane ); float dot = PlaneDiff( tr.modelorg, node->plane );
side = (dot >= 0.0f) ? 0 : 1; int side = (dot >= 0.0f) ? 0 : 1;
// recurse down the children, front side first // recurse down the children, front side first
node_children( children, node, WORLDMODEL ); R_RecursiveWorldNode( node_child( node, side, WORLDMODEL ), clipflags );
R_RecursiveWorldNode( children[side], clipflags );
firstsurface = node_firstsurface( node, WORLDMODEL ); int firstsurface = node_firstsurface( node, WORLDMODEL );
numsurfaces = node_numsurfaces( node, WORLDMODEL ); int numsurfaces = node_numsurfaces( node, WORLDMODEL );
// draw stuff // draw stuff
for( c = numsurfaces, surf = WORLDMODEL->surfaces + firstsurface; c; c--, surf++ ) for( int i = firstsurface; i < firstsurface + numsurfaces; i++ )
{ {
msurface_t *surf = &WORLDMODEL->surfaces[i];
if( R_CullSurface( surf, &RI.frustum, clipflags )) if( R_CullSurface( surf, &RI.frustum, clipflags ))
continue; continue;
@@ -3491,7 +3476,7 @@ loc0:
} }
// recurse down the back side // recurse down the back side
node = children[!side]; node = node_child( node, !side, WORLDMODEL );
goto loc0; goto loc0;
} }
@@ -3567,7 +3552,6 @@ static void R_DrawWorldTopView( mnode_t *node, uint clipflags )
do do
{ {
mnode_t *children[2];
int numsurfaces, firstsurface; int numsurfaces, firstsurface;
if( node->contents == CONTENTS_SOLID ) if( node->contents == CONTENTS_SOLID )
@@ -3625,9 +3609,8 @@ static void R_DrawWorldTopView( mnode_t *node, uint clipflags )
} }
// recurse down both children, we don't care the order... // recurse down both children, we don't care the order...
node_children( children, node, WORLDMODEL ); R_DrawWorldTopView( node_child( node, 0, WORLDMODEL ), clipflags );
R_DrawWorldTopView( children[0], clipflags ); node = node_child( node, 1, WORLDMODEL );
node = children[1];
} while( node ); } while( node );
} }

View File

@@ -559,7 +559,6 @@ static void R_RecursiveWorldNode( mnode_t *node, int clipflags )
} }
else else
{ {
mnode_t *children[2];
int firstsurface; int firstsurface;
// node is just a decision point, so go down the apropriate sides // node is just a decision point, so go down the apropriate sides
@@ -589,8 +588,7 @@ static void R_RecursiveWorldNode( mnode_t *node, int clipflags )
side = 1; side = 1;
// recurse down the children, front side first // recurse down the children, front side first
node_children( children, node, WORLDMODEL ); R_RecursiveWorldNode( node_child( node, side, WORLDMODEL ), clipflags );
R_RecursiveWorldNode( children[side], clipflags );
// draw stuff // draw stuff
c = node_numsurfaces( node, WORLDMODEL ); c = node_numsurfaces( node, WORLDMODEL );
@@ -634,7 +632,7 @@ static void R_RecursiveWorldNode( mnode_t *node, int clipflags )
} }
// recurse down the back side // recurse down the back side
R_RecursiveWorldNode( children[!side], clipflags ); R_RecursiveWorldNode( node_child( node, !side, WORLDMODEL ), clipflags );
} }
} }

View File

@@ -705,10 +705,7 @@ static void R_DecalNodeSurfaces( model_t *model, mnode_t *node, decalinfo_t *dec
static void R_DecalNode( model_t *model, mnode_t *node, decalinfo_t *decalinfo ) static void R_DecalNode( model_t *model, mnode_t *node, decalinfo_t *decalinfo )
{ {
mplane_t *splitplane; mplane_t *splitplane;
float dist; float dist;
mnode_t *children[2];
Assert( node != NULL );
if( node->contents < 0 ) if( node->contents < 0 )
{ {
@@ -718,31 +715,22 @@ static void R_DecalNode( model_t *model, mnode_t *node, decalinfo_t *decalinfo )
splitplane = node->plane; splitplane = node->plane;
dist = DotProduct( decalinfo->m_Position, splitplane->normal ) - splitplane->dist; dist = DotProduct( decalinfo->m_Position, splitplane->normal ) - splitplane->dist;
node_children( children, node, model );
// This is arbitrarily set to 10 right now. In an ideal world we'd have the
// exact surface but we don't so, this tells me which planes are "sort of
// close" to the gunshot -- the gunshot is actually 4 units in front of the
// wall (see dlls\weapons.cpp). We also need to check to see if the decal
// actually intersects the texture space of the surface, as this method tags
// parallel surfaces in the same node always.
// JAY: This still tags faces that aren't correct at edges because we don't
// have a surface normal
if( dist > decalinfo->m_Size ) if( dist > decalinfo->m_Size )
{ {
R_DecalNode( model, children[0], decalinfo ); R_DecalNode( model, node_child( node, 0, model ), decalinfo );
} }
else if( dist < -decalinfo->m_Size ) else if( dist < -decalinfo->m_Size )
{ {
R_DecalNode( model, children[1], decalinfo ); R_DecalNode( model, node_child( node, 1, model ), decalinfo );
} }
else else
{ {
if( dist < DECAL_DISTANCE && dist > -DECAL_DISTANCE ) if( dist < DECAL_DISTANCE && dist > -DECAL_DISTANCE )
R_DecalNodeSurfaces( model, node, decalinfo ); R_DecalNodeSurfaces( model, node, decalinfo );
R_DecalNode( model, children[0], decalinfo ); R_DecalNode( model, node_child( node, 0, model ), decalinfo );
R_DecalNode( model, children[1], decalinfo ); R_DecalNode( model, node_child( node, 1, model ), decalinfo );
} }
} }

View File

@@ -107,7 +107,6 @@ void R_MarkLights( dlight_t *light, int bit, mnode_t *node )
float dist; float dist;
msurface_t *surf; msurface_t *surf;
int i; int i;
mnode_t *children[2];
int firstsurface, numsurfaces; int firstsurface, numsurfaces;
if( !node || node->contents < 0 ) if( !node || node->contents < 0 )
@@ -115,18 +114,17 @@ void R_MarkLights( dlight_t *light, int bit, mnode_t *node )
dist = PlaneDiff( light->origin, node->plane ); dist = PlaneDiff( light->origin, node->plane );
node_children( children, node, RI.currentmodel );
firstsurface = node_firstsurface( node, RI.currentmodel ); firstsurface = node_firstsurface( node, RI.currentmodel );
numsurfaces = node_numsurfaces( node, RI.currentmodel ); numsurfaces = node_numsurfaces( node, RI.currentmodel );
if( dist > light->radius ) if( dist > light->radius )
{ {
R_MarkLights( light, bit, children[0] ); R_MarkLights( light, bit, node_child( node, 0, RI.currentmodel ));
return; return;
} }
if( dist < -light->radius ) if( dist < -light->radius )
{ {
R_MarkLights( light, bit, children[1] ); R_MarkLights( light, bit, node_child( node, 1, RI.currentmodel ));
return; return;
} }
@@ -146,8 +144,8 @@ void R_MarkLights( dlight_t *light, int bit, mnode_t *node )
surf->dlightbits |= bit; surf->dlightbits |= bit;
} }
R_MarkLights( light, bit, children[0] ); R_MarkLights( light, bit, node_child( node, 0, RI.currentmodel ));
R_MarkLights( light, bit, children[1] ); R_MarkLights( light, bit, node_child( node, 1, RI.currentmodel ));
} }
/* /*
@@ -207,7 +205,6 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
msurface_t *surf; msurface_t *surf;
matrix3x4 tbn; matrix3x4 tbn;
vec3_t mid; vec3_t mid;
mnode_t *children[2];
int firstsurface, numsurfaces; int firstsurface, numsurfaces;
// didn't hit anything // didn't hit anything
@@ -217,7 +214,6 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
return false; return false;
} }
node_children( children, node, model );
firstsurface = node_firstsurface( node, model ); firstsurface = node_firstsurface( node, model );
numsurfaces = node_numsurfaces( node, model ); numsurfaces = node_numsurfaces( node, model );
@@ -227,7 +223,7 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
side = front < 0; side = front < 0;
if(( back < 0 ) == side ) if(( back < 0 ) == side )
return R_RecursiveLightPoint( model, children[side], p1f, p2f, cv, start, end ); return R_RecursiveLightPoint( model, node_child( node, side, model ), p1f, p2f, cv, start, end );
frac = front / ( front - back ); frac = front / ( front - back );
@@ -235,7 +231,7 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
midf = p1f + ( p2f - p1f ) * frac; midf = p1f + ( p2f - p1f ) * frac;
// co down front side // co down front side
if( R_RecursiveLightPoint( model, children[side], p1f, midf, cv, start, mid )) if( R_RecursiveLightPoint( model, node_child( node, side, model ), p1f, midf, cv, start, mid ))
return true; // hit something return true; // hit something
if(( back < 0 ) == side ) if(( back < 0 ) == side )
@@ -337,7 +333,7 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
} }
// go down back side // go down back side
return R_RecursiveLightPoint( model, children[!side], midf, p2f, cv, mid, end ); return R_RecursiveLightPoint( model, node_child( node, !side, model ), midf, p2f, cv, mid, end );
} }
/* /*