From f49c6cbde2028f1adfbe24f4f4a2a0525f85acb7 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. --- src/gl/renderer/gl_renderer.cpp | 2 +- src/gl/scene/gl_bsp.cpp | 2 +- src/gl/scene/gl_scene.cpp | 2 +- src/hwrenderer/scene/hw_fakeflat.cpp | 6 ++---- src/hwrenderer/scene/hw_sprites.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 +- 12 files changed, 35 insertions(+), 40 deletions(-) diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index eab8fa0ff..98aee05c0 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -558,7 +558,7 @@ void FGLRenderer::DrawBlend(sector_t * viewsector, bool FixedColormap, bool doco { if (!viewsector->e->XFloor.ffloors.Size()) { - if (viewsector->heightsec && !(viewsector->MoreFlags&SECF_IGNOREHEIGHTSEC)) + if (viewsector->GetHeightSec()) { auto s = viewsector->heightsec; blendv = s->floorplane.PointOnSide(r_viewpoint.Pos) < 0? s->bottommap : s->ceilingplane.PointOnSide(r_viewpoint.Pos) < 0 ? s->topmap : s->midmap; diff --git a/src/gl/scene/gl_bsp.cpp b/src/gl/scene/gl_bsp.cpp index 83620cbb2..169b7513c 100644 --- a/src/gl/scene/gl_bsp.cpp +++ b/src/gl/scene/gl_bsp.cpp @@ -497,7 +497,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_scene.cpp b/src/gl/scene/gl_scene.cpp index ef17b7128..99cb6e112 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -103,7 +103,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) && diff --git a/src/hwrenderer/scene/hw_fakeflat.cpp b/src/hwrenderer/scene/hw_fakeflat.cpp index 6b535bdad..3b0c35042 100644 --- a/src/hwrenderer/scene/hw_fakeflat.cpp +++ b/src/hwrenderer/scene/hw_fakeflat.cpp @@ -160,9 +160,7 @@ bool hw_CheckClip(side_t * sidedef, sector_t * frontsector, sector_t * backsecto area_t hw_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; @@ -189,7 +187,7 @@ area_t hw_CheckViewArea(vertex_t *v1, vertex_t *v2, sector_t *frontsector, secto //========================================================================== sector_t * hw_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/hwrenderer/scene/hw_sprites.cpp b/src/hwrenderer/scene/hw_sprites.cpp index ad2118063..6e20960a1 100644 --- a/src/hwrenderer/scene/hw_sprites.cpp +++ b/src/hwrenderer/scene/hw_sprites.cpp @@ -309,7 +309,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 e0eca11db..b5f10b69e 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -1068,30 +1068,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 c718bdeab..50733318a 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -4221,6 +4221,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 da20dec4a..3c140f5f7 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -1374,6 +1374,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 c5c487c9a..12406b5c0 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 fd702c596..2ab250d1d 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -654,7 +654,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 a3e1b1bd9..a7ba00c0c 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) {