From 30754dfa41e24a179eba508ce167fef007affebd Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 6 Apr 2023 14:42:56 +0000 Subject: [PATCH] Merge branch 'raised-sector-culling' into 'master' Automatic level culling for raised floors / lowered ceilings See merge request KartKrew/Kart!1145 --- src/r_bsp.cpp | 33 +++++++++++++++++++++++++++++---- src/r_bsp.h | 1 + src/r_segs.c | 25 ++++++++++++++----------- 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index 939e96fe3..33c5bdbc6 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -47,6 +47,10 @@ drawseg_t *ds_p = NULL; // indicates doors closed wrt automap bugfix: INT32 doorclosed; +// A wall was drawn covering the whole screen, which means we +// can block off the BSP across that seg. +boolean g_walloffscreen; + boolean R_NoEncore(sector_t *sector, levelflat_t *flat, boolean ceiling) { const boolean invertEncore = (sector->flags & MSF_INVERTENCORE); @@ -109,6 +113,7 @@ enum class ClipType // e.g. single sided LineDefs (middle texture) // that entirely block the view. kSolid, + kSolidDontRender, // Clips the given range of columns, but does not include it in the clip list. // Does handle windows, e.g. LineDefs with upper and lower texture. @@ -148,7 +153,10 @@ void R_ClipWallSegment(INT32 first, INT32 last) if (last < start->first - 1) { // Post is entirely visible (above start), so insert a new clippost. - R_StoreWallRange(first, last); + if constexpr (Type != ClipType::kSolidDontRender) + { + R_StoreWallRange(first, last); + } if constexpr (Type != ClipType::kPass) { @@ -171,7 +179,10 @@ void R_ClipWallSegment(INT32 first, INT32 last) } // There is a fragment above *start. - R_StoreWallRange(first, start->first - 1); + if constexpr (Type != ClipType::kSolidDontRender) + { + R_StoreWallRange(first, start->first - 1); + } if constexpr (Type != ClipType::kPass) { @@ -188,7 +199,11 @@ void R_ClipWallSegment(INT32 first, INT32 last) while (last >= (next+1)->first - 1) { // There is a fragment between two posts. - R_StoreWallRange(start->last + 1, (start+1)->first - 1); + if constexpr (Type != ClipType::kSolidDontRender) + { + R_StoreWallRange(next->last + 1, (next+1)->first - 1); + } + next++; if (last <= next->last) @@ -206,7 +221,10 @@ void R_ClipWallSegment(INT32 first, INT32 last) } // There is a fragment after *next. - R_StoreWallRange(start->last + 1, last); + if constexpr (Type != ClipType::kSolidDontRender) + { + R_StoreWallRange(next->last + 1, last); + } if constexpr (Type != ClipType::kPass) { @@ -629,10 +647,17 @@ static void R_AddLine(seg_t *line) return; clippass: + g_walloffscreen = false; R_ClipWallSegment(x1, x2 - 1); + + if (g_walloffscreen) + { + R_ClipWallSegment(x1, x2 -1); + } return; clipsolid: + g_walloffscreen = false; R_ClipWallSegment(x1, x2 - 1); } diff --git a/src/r_bsp.h b/src/r_bsp.h index d9272cdfa..e1e343ca4 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -39,6 +39,7 @@ extern drawseg_t *curdrawsegs; extern drawseg_t *drawsegs; extern drawseg_t *ds_p; extern INT32 doorclosed; +extern boolean g_walloffscreen; // BSP? void R_ClearClipSegs(void); diff --git a/src/r_segs.c b/src/r_segs.c index 231d2010f..189121731 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -2710,23 +2710,26 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (toptexture) { - pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale); - pixhighstep = -FixedMul (rw_scalestep,worldhigh); + fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2); - if (backsector->c_slope) { - fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2); - pixhighstep = (topfracend-pixhigh)/(range); - } + pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale); + pixhighstep = (topfracend-pixhigh)/(range); + + // If the lowest part of a ceiling stretching down covers the entire screen + if (min(pixhigh, topfracend)>>HEIGHTBITS >= viewheight-1) + g_walloffscreen = true; } if (bottomtexture) { + fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2); + pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale); - pixlowstep = -FixedMul (rw_scalestep,worldlow); - if (backsector->f_slope) { - fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2); - pixlowstep = (bottomfracend-pixlow)/(range); - } + pixlowstep = (bottomfracend-pixlow)/(range); + + // If the highest part of a floor stretching up covers the entire screen + if ((max(pixlow, bottomfracend)+HEIGHTUNIT-1)>>HEIGHTBITS <= 0) + g_walloffscreen = true; } {