From 8a3a293bf82562a9de1568f0055e82022244e656 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 1 May 2018 09:47:09 +0200 Subject: [PATCH] - use sector_t::GetHeightSec consistently and optimize it. This was all over the place, with half of it using the function and half doing incomplete checks on the underlying variables. Also did some optimization on the IGNOREHEIGHTSEC flag: Putting it on the destination sector instead of the model sector makes the check even simpler and allows to precalculate the effect of 3D floors on the heightsec, which previously had to be run on every call and made the function too complex for inlining. (cherry picked from commit f49c6cbde2028f1adfbe24f4f4a2a0525f85acb7) # Conflicts: # src/gl/renderer/gl_renderer.cpp # src/hwrenderer/scene/hw_sprites.cpp --- src/gl/scene/gl_bsp.cpp | 2 +- src/gl/scene/gl_fakeflat.cpp | 6 ++---- src/gl/scene/gl_scene.cpp | 4 ++-- src/gl/scene/gl_sprite.cpp | 2 +- src/p_sectors.cpp | 24 ----------------------- src/p_setup.cpp | 17 ++++++++++++++++ src/p_spec.cpp | 1 + src/polyrenderer/scene/poly_sprite.cpp | 4 ++-- src/r_defs.h | 7 ++++++- src/swrenderer/scene/r_opaque_pass.cpp | 6 ++---- src/swrenderer/things/r_visiblesprite.cpp | 2 +- 11 files changed, 35 insertions(+), 40 deletions(-) diff --git a/src/gl/scene/gl_bsp.cpp b/src/gl/scene/gl_bsp.cpp index 64b8c92e3..45c85e1f9 100644 --- a/src/gl/scene/gl_bsp.cpp +++ b/src/gl/scene/gl_bsp.cpp @@ -495,7 +495,7 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub) // but undetermined heightsec state. This can only happen if the // subsector is obstructed but not excluded due to a large bounding box. // Due to the way a BSP works such a subsector can never be visible - if (!sector->heightsec || sector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC || in_area!=area_default) + if (!sector->GetHeightSec() || in_area!=area_default) { if (sector != sub->render_sector) { diff --git a/src/gl/scene/gl_fakeflat.cpp b/src/gl/scene/gl_fakeflat.cpp index e39eeb175..fe7ff9bcf 100644 --- a/src/gl/scene/gl_fakeflat.cpp +++ b/src/gl/scene/gl_fakeflat.cpp @@ -163,9 +163,7 @@ bool gl_CheckClip(side_t * sidedef, sector_t * frontsector, sector_t * backsecto area_t GLSceneDrawer::CheckViewArea(vertex_t *v1, vertex_t *v2, sector_t *frontsector, sector_t *backsector) { - if ( - (backsector->heightsec && !(backsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC)) && - (!frontsector->heightsec || frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC)) + if (backsector->GetHeightSec() && !frontsector->GetHeightSec()) { sector_t * s = backsector->heightsec; @@ -192,7 +190,7 @@ area_t GLSceneDrawer::CheckViewArea(vertex_t *v1, vertex_t *v2, sector_t *fronts //========================================================================== sector_t * gl_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool back) { - if (!sec->heightsec || sec->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC || sec->heightsec==sec) + if (!sec->GetHeightSec() || sec->heightsec==sec) { // check for backsectors with the ceiling lower than the floor. These will create // visual glitches because upper amd lower textures overlap. diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 548bc7fe7..e19e14458 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -125,7 +125,7 @@ void GLSceneDrawer::SetViewArea() r_viewpoint.sector = R_PointInSubsector(r_viewpoint.Pos)->render_sector; // Get the heightsec state from the render sector, not the current one! - if (r_viewpoint.sector->heightsec && !(r_viewpoint.sector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC)) + if (r_viewpoint.sector->GetHeightSec()) { in_area = r_viewpoint.Pos.Z <= r_viewpoint.sector->heightsec->floorplane.ZatPoint(r_viewpoint.Pos) ? area_below : (r_viewpoint.Pos.Z > r_viewpoint.sector->heightsec->ceilingplane.ZatPoint(r_viewpoint.Pos) && @@ -557,7 +557,7 @@ void GLSceneDrawer::DrawBlend(sector_t * viewsector) { if (!viewsector->e->XFloor.ffloors.Size()) { - if (viewsector->heightsec && !(viewsector->MoreFlags&SECF_IGNOREHEIGHTSEC)) + if (viewsector->GetHeightSec()) { switch (in_area) { diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index c7efe1eb8..d63584f67 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -617,7 +617,7 @@ void GLSprite::PerformSpriteClipAdjustment(AActor *thing, const DVector2 &thingp } } } - else if (thing->Sector->heightsec && !(thing->Sector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC)) + else if (thing->Sector->GetHeightSec()) { if (thing->flags2&MF2_ONMOBJ && thing->floorz == thing->Sector->heightsec->floorplane.ZatPoint(thingpos)) diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index f26c7e229..aa153ba3a 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -1069,30 +1069,6 @@ FSectorPortal *sector_t::ValidatePortal(int which) // //===================================================================================== -sector_t *sector_t::GetHeightSec() const -{ - if (heightsec == NULL) - { - return NULL; - } - if (heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) - { - return NULL; - } - if (e && e->XFloor.ffloors.Size()) - { - // If any of these fake floors render their planes, ignore heightsec. - for (unsigned i = e->XFloor.ffloors.Size(); i-- > 0; ) - { - if ((e->XFloor.ffloors[i]->flags & (FF_EXISTS | FF_RENDERPLANES)) == (FF_EXISTS | FF_RENDERPLANES)) - { - return NULL; - } - } - } - return heightsec; -} - DEFINE_ACTION_FUNCTION(_Sector, GetHeightSec) { PARAM_SELF_STRUCT_PROLOGUE(sector_t); diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 565e42783..e09afbaa9 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -4197,6 +4197,23 @@ void P_SetupLevel (const char *lumpname, int position) AnnounceGameStart (); } + // This check was previously done at run time each time the heightsec was checked. + // However, since 3D floors are static data, we can easily precalculate this and store it in the sector's flags for quick access. + for (auto &s : level.sectors) + { + if (s.heightsec != nullptr) + { + // If any of these 3D floors render their planes, ignore heightsec. + for (auto &ff : s.e->XFloor.ffloors) + { + if ((ff->flags & (FF_EXISTS | FF_RENDERPLANES)) == (FF_EXISTS | FF_RENDERPLANES)) + { + s.MoreFlags |= SECF_IGNOREHEIGHTSEC; // mark the heightsec inactive. + } + } + } + } + P_ResetSightCounters (true); //Printf ("free memory: 0x%x\n", Z_FreeMemory()); diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 0f639a991..e532504c8 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -1392,6 +1392,7 @@ void P_SpawnSpecials (void) { level.sectors[s].heightsec = sec; sec->e->FakeFloor.Sectors.Push(&level.sectors[s]); + level.sectors[s].MoreFlags |= (sec->MoreFlags & SECF_IGNOREHEIGHTSEC); // copy this to the destination sector for easier checking. level.sectors[s].AdjustFloorClip(); } break; diff --git a/src/polyrenderer/scene/poly_sprite.cpp b/src/polyrenderer/scene/poly_sprite.cpp index 5733c6c27..7cec516f2 100644 --- a/src/polyrenderer/scene/poly_sprite.cpp +++ b/src/polyrenderer/scene/poly_sprite.cpp @@ -182,7 +182,7 @@ double RenderPolySprite::GetSpriteFloorZ(AActor *thing, const DVector2 &thingpos return floorh; } - if (thing->Sector->heightsec && !(thing->Sector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC)) + if (thing->Sector->GetHeightSec()) { if (thing->flags2&MF2_ONMOBJ && thing->floorz == thing->Sector->heightsec->floorplane.ZatPoint(thingpos)) { @@ -204,7 +204,7 @@ double RenderPolySprite::GetSpriteCeilingZ(AActor *thing, const DVector2 &thingp return ceilingh; } - if (thing->Sector->heightsec && !(thing->Sector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC)) + if (thing->Sector->GetHeightSec()) { if (thing->flags2&MF2_ONMOBJ && thing->ceilingz == thing->Sector->heightsec->ceilingplane.ZatPoint(thingpos)) { diff --git a/src/r_defs.h b/src/r_defs.h index 6a3dfac76..b4b3bccee 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -653,7 +653,12 @@ public: void ClosestPoint(const DVector2 &pos, DVector2 &out) const; int GetFloorLight () const; int GetCeilingLight () const; - sector_t *GetHeightSec() const; + + sector_t *GetHeightSec() const + { + return (MoreFlags & SECF_IGNOREHEIGHTSEC)? nullptr : heightsec; + } + double GetFriction(int plane = sector_t::floor, double *movefac = NULL) const; bool TriggerSectorActions(AActor *thing, int activation); diff --git a/src/swrenderer/scene/r_opaque_pass.cpp b/src/swrenderer/scene/r_opaque_pass.cpp index b9484f624..3ea7dd525 100644 --- a/src/swrenderer/scene/r_opaque_pass.cpp +++ b/src/swrenderer/scene/r_opaque_pass.cpp @@ -554,8 +554,7 @@ namespace swrenderer VisiblePlane *ceilingplane = frontsector->ceilingplane.PointOnSide(Thread->Viewport->viewpoint.Pos) > 0 || frontsector->GetTexture(sector_t::ceiling) == skyflatnum || portal != nullptr || - (frontsector->heightsec && - !(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) && + (frontsector->GetHeightSec() && frontsector->heightsec->GetTexture(sector_t::floor) == skyflatnum) ? Thread->PlaneList->FindPlane(frontsector->ceilingplane, // killough 3/8/98 frontsector->GetTexture(sector_t::ceiling), @@ -597,8 +596,7 @@ namespace swrenderer VisiblePlane *floorplane = frontsector->floorplane.PointOnSide(Thread->Viewport->viewpoint.Pos) > 0 || // killough 3/7/98 frontsector->GetTexture(sector_t::floor) == skyflatnum || portal != nullptr || - (frontsector->heightsec && - !(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) && + (frontsector->GetHeightSec() && frontsector->heightsec->GetTexture(sector_t::ceiling) == skyflatnum) ? Thread->PlaneList->FindPlane(frontsector->floorplane, frontsector->GetTexture(sector_t::floor), diff --git a/src/swrenderer/things/r_visiblesprite.cpp b/src/swrenderer/things/r_visiblesprite.cpp index 458e83dbb..cc9ce8825 100644 --- a/src/swrenderer/things/r_visiblesprite.cpp +++ b/src/swrenderer/things/r_visiblesprite.cpp @@ -173,7 +173,7 @@ namespace swrenderer hzb = spr->gzb; } - if (spr->heightsec && !(spr->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC)) + if (spr->heightsec) { // only things in specially marked sectors if (spr->FakeFlatStat != WaterFakeSide::AboveCeiling) {