diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index eab8fa0ff9..98aee05c08 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 83620cbb24..169b7513ca 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 ef17b71282..99cb6e112c 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 6b535bdad9..3b0c350429 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 ad21180638..6e20960a1a 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 e0eca11dbb..b5f10b69ee 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 c718bdeaba..50733318ab 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 da20dec4af..3c140f5f78 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 c5c487c9ac..12406b5c04 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 fd702c5964..2ab250d1d0 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 a3e1b1bd97..a7ba00c0c1 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 458e83dbb0..cc9ce8825d 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) {