From 44e69451cf8fb6b16fd2bdcf50b3127c00cf8f54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Tue, 15 Oct 2024 13:24:00 -0300 Subject: [PATCH] Hook up 3d floor updates to the level mesh --- src/g_level.cpp | 1 + src/g_levellocals.h | 2 + src/gamedata/r_defs.h | 1 + src/levelmeshhelper.cpp | 102 +++++++++++++++++--- src/levelmeshhelper.h | 40 +++++--- src/maploader/specials.cpp | 7 ++ src/rendering/hwrenderer/doom_levelmesh.cpp | 22 ++--- src/rendering/hwrenderer/doom_levelmesh.h | 22 ++--- 8 files changed, 153 insertions(+), 44 deletions(-) diff --git a/src/g_level.cpp b/src/g_level.cpp index d3d76b2bf..ab4fa15c0 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1866,6 +1866,7 @@ void FLevelLocals::Init() musicorder = info->musicorder; MusicVolume = 1.f; HasHeightSecs = false; + SecCorrelations.Clear(); LevelName = info->LookupLevelName(); NextMap = info->NextMap; diff --git a/src/g_levellocals.h b/src/g_levellocals.h index b54a91ea0..277849111 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -680,6 +680,8 @@ public: bool HasDynamicLights; // Another render optimization for maps with no lights at all. int frozenstate; + TMap> SecCorrelations; // links sectors to a list of sectors it provides fake height/3d floors for + double teamdamage; // former OpenGL-exclusive properties that should also be usable by the true color software renderer. diff --git a/src/gamedata/r_defs.h b/src/gamedata/r_defs.h index 50b491ece..b6526cc62 100644 --- a/src/gamedata/r_defs.h +++ b/src/gamedata/r_defs.h @@ -729,6 +729,7 @@ struct sector_t int ibocount; // number of indices per plane (identical for all planes.) If this is -1 the index buffer is not in use. bool HasLightmaps = false; // Sector has lightmaps, each subsector vertex needs its own unique lightmap UV data + bool Sec3dControlUseMidTex = false; // Below are all properties which are not used by the renderer. diff --git a/src/levelmeshhelper.cpp b/src/levelmeshhelper.cpp index d5906094a..04e4b8b2a 100644 --- a/src/levelmeshhelper.cpp +++ b/src/levelmeshhelper.cpp @@ -1,23 +1,103 @@ #include "levelmeshhelper.h" +#include "r_defs.h" +#include "g_levellocals.h" + +#define PROPAGATE_CORRELATIONS_SECTOR(func)\ + func(sector);\ + TArray* c = sector->Level->SecCorrelations.CheckKey(sector->Index());\ + if(c) for(int index : *c) func(§or->Level->sectors[index]); + +#define PROPAGATE_CORRELATIONS_SECTOR2(func, arg2)\ + func(sector, arg2);\ + TArray* c = sector->Level->SecCorrelations.CheckKey(sector->Index());\ + if(c) for(int index : *c) func(§or->Level->sectors[index], arg2); + +void UpdateLevelMesh::FloorHeightChanged(sector_t* sector) +{ + PROPAGATE_CORRELATIONS_SECTOR(OnFloorHeightChanged); +} + +void UpdateLevelMesh::CeilingHeightChanged(sector_t* sector) +{ + PROPAGATE_CORRELATIONS_SECTOR(OnCeilingHeightChanged); +} + +void UpdateLevelMesh::MidTex3DHeightChanged(sector_t* sector) +{ + PROPAGATE_CORRELATIONS_SECTOR(OnMidTex3DHeightChanged); +} + +void UpdateLevelMesh::FloorTextureChanged(sector_t* sector) +{ + PROPAGATE_CORRELATIONS_SECTOR(OnFloorTextureChanged); +} +void UpdateLevelMesh::CeilingTextureChanged(sector_t* sector) +{ + PROPAGATE_CORRELATIONS_SECTOR(OnCeilingTextureChanged); +} + +void UpdateLevelMesh::SectorChangedOther(sector_t* sector) +{ + PROPAGATE_CORRELATIONS_SECTOR(OnSectorChangedOther); +} + +void UpdateLevelMesh::SideTextureChanged(side_t* side, int section) +{ + OnSideTextureChanged(side, section); + + TArray* c = side->sector->Level->SecCorrelations.CheckKey(side->sector->Index()); + // if midtex changed, and is a 3d floor that should use the midtexture (and not the line itself's upper/lower), propagate change to all lines in affected sectors + if(c && section == 1 && side->sector->Sec3dControlUseMidTex) + { + for(int index : *c) + { + for(auto line : side->sector->Level->sectors[index].Lines) + { + OnSideTextureChanged(line->sidedef[0], section); // should only need the first side? + // OnSideTextureChanged(&line->sidedef[1], section); + } + } + } +} + +void UpdateLevelMesh::SideDecalsChanged(side_t* side) +{ // Decals shouldn't propagate + return OnSideDecalsChanged(side); +} + +void UpdateLevelMesh::SectorLightChanged(sector_t* sector) +{ + PROPAGATE_CORRELATIONS_SECTOR(OnSectorLightChanged); +} + +void UpdateLevelMesh::SectorLightThinkerCreated(sector_t* sector, DLighting* lightthinker) +{ + PROPAGATE_CORRELATIONS_SECTOR2(OnSectorLightThinkerCreated, lightthinker); +} + +void UpdateLevelMesh::SectorLightThinkerDestroyed(sector_t* sector, DLighting* lightthinker) +{ + PROPAGATE_CORRELATIONS_SECTOR2(OnSectorLightThinkerDestroyed, lightthinker); +} struct NullLevelMeshUpdater : UpdateLevelMesh { - void FloorHeightChanged(sector_t* sector) override {} - void CeilingHeightChanged(sector_t* sector) override {} - void MidTex3DHeightChanged(sector_t* sector) override {} + void OnFloorHeightChanged(sector_t* sector) override {} + void OnCeilingHeightChanged(sector_t* sector) override {} + void OnMidTex3DHeightChanged(sector_t* sector) override {} - void FloorTextureChanged(sector_t* sector) override {} - void CeilingTextureChanged(sector_t* sector) override {} + void OnFloorTextureChanged(sector_t* sector) override {} + void OnCeilingTextureChanged(sector_t* sector) override {} - void SectorChangedOther(sector_t* sector) override {} + void OnSectorChangedOther(sector_t* sector) override {} - void SideTextureChanged(side_t* side, int section) override {} - void SideDecalsChanged(side_t* side) override {} + void OnSideTextureChanged(side_t* side, int section) override {} + void OnSideDecalsChanged(side_t* side) override {} - void SectorLightChanged(sector_t* sector) override {} - void SectorLightThinkerCreated(sector_t* sector, DLighting* lightthinker) override {} - void SectorLightThinkerDestroyed(sector_t* sector, DLighting* lightthinker) override {} + void OnSectorLightChanged(sector_t* sector) override {} + void OnSectorLightThinkerCreated(sector_t* sector, DLighting* lightthinker) override {} + void OnSectorLightThinkerDestroyed(sector_t* sector, DLighting* lightthinker) override {} }; static NullLevelMeshUpdater nullUpdater; diff --git a/src/levelmeshhelper.h b/src/levelmeshhelper.h index 3ba0b2cde..89611cfca 100644 --- a/src/levelmeshhelper.h +++ b/src/levelmeshhelper.h @@ -8,21 +8,39 @@ class DLighting; struct UpdateLevelMesh { - virtual void FloorHeightChanged(sector_t *sector) = 0; - virtual void CeilingHeightChanged(sector_t *sector) = 0; - virtual void MidTex3DHeightChanged(sector_t *sector) = 0; + //3d floor-aware + void FloorHeightChanged(sector_t *sector); + void CeilingHeightChanged(sector_t *sector); + void MidTex3DHeightChanged(sector_t *sector); - virtual void FloorTextureChanged(sector_t *sector) = 0; - virtual void CeilingTextureChanged(sector_t *sector) = 0; + void FloorTextureChanged(sector_t *sector); + void CeilingTextureChanged(sector_t *sector); - virtual void SectorChangedOther(sector_t *sector) = 0; + void SectorChangedOther(sector_t *sector); - virtual void SideTextureChanged(side_t *side, int section) = 0; - virtual void SideDecalsChanged(side_t* side) = 0; + void SideTextureChanged(side_t *side, int section); + void SideDecalsChanged(side_t* side); - virtual void SectorLightChanged(sector_t* sector) = 0; - virtual void SectorLightThinkerCreated(sector_t* sector, DLighting* lightthinker) = 0; - virtual void SectorLightThinkerDestroyed(sector_t* sector, DLighting* lightthinker) = 0; + void SectorLightChanged(sector_t* sector); + void SectorLightThinkerCreated(sector_t* sector, DLighting* lightthinker); + void SectorLightThinkerDestroyed(sector_t* sector, DLighting* lightthinker); + + //raw + virtual void OnFloorHeightChanged(sector_t *sector) = 0; + virtual void OnCeilingHeightChanged(sector_t *sector) = 0; + virtual void OnMidTex3DHeightChanged(sector_t *sector) = 0; + + virtual void OnFloorTextureChanged(sector_t *sector) = 0; + virtual void OnCeilingTextureChanged(sector_t *sector) = 0; + + virtual void OnSectorChangedOther(sector_t *sector) = 0; + + virtual void OnSideTextureChanged(side_t *side, int section) = 0; + virtual void OnSideDecalsChanged(side_t* side) = 0; + + virtual void OnSectorLightChanged(sector_t* sector) = 0; + virtual void OnSectorLightThinkerCreated(sector_t* sector, DLighting* lightthinker) = 0; + virtual void OnSectorLightThinkerDestroyed(sector_t* sector, DLighting* lightthinker) = 0; }; extern UpdateLevelMesh* LevelMeshUpdater; diff --git a/src/maploader/specials.cpp b/src/maploader/specials.cpp index 47663e812..d2311ab27 100644 --- a/src/maploader/specials.cpp +++ b/src/maploader/specials.cpp @@ -721,6 +721,7 @@ void MapLoader::SpawnSpecials () auto itr = Level->GetSectorTagIterator(line.args[0]); while ((s = itr.Next()) >= 0) { + Level->SecCorrelations[sec->Index()].Push(s); Level->sectors[s].heightsec = sec; sec->e->FakeFloor.Sectors.Push(&Level->sectors[s]); Level->sectors[s].MoreFlags |= (sec->MoreFlags & SECMF_IGNOREHEIGHTSEC); // copy this to the destination sector for easier checking. @@ -1008,6 +1009,12 @@ int MapLoader::Set3DFloor(line_t * line, int param, int param2, int alpha) } P_Add3DFloor(ss, sec, line, flags, alpha); + Level->SecCorrelations[sec->Index()].Push(s); + + if(!(flags & (FF_UPPERTEXTURE | FF_LOWERTEXTURE))) + { + sec->Sec3dControlUseMidTex = true; + } } // To be 100% safe this should be done even if the alpha by texture value isn't used. if (!line->sidedef[0]->GetTexture(side_t::top).isValid()) diff --git a/src/rendering/hwrenderer/doom_levelmesh.cpp b/src/rendering/hwrenderer/doom_levelmesh.cpp index f988ebefa..ddcf1dccb 100644 --- a/src/rendering/hwrenderer/doom_levelmesh.cpp +++ b/src/rendering/hwrenderer/doom_levelmesh.cpp @@ -610,7 +610,7 @@ void DoomLevelMesh::FreeFlat(FLevelLocals& doomMap, unsigned int sectorIndex) Flats[sectorIndex].Uniforms.Clear(); } -void DoomLevelMesh::FloorHeightChanged(sector_t* sector) +void DoomLevelMesh::OnFloorHeightChanged(sector_t* sector) { UpdateFlat(sector->Index(), SurfaceUpdateType::Full); for (line_t* line : sector->Lines) @@ -622,7 +622,7 @@ void DoomLevelMesh::FloorHeightChanged(sector_t* sector) } } -void DoomLevelMesh::CeilingHeightChanged(sector_t* sector) +void DoomLevelMesh::OnCeilingHeightChanged(sector_t* sector) { UpdateFlat(sector->Index(), SurfaceUpdateType::Full); for (line_t* line : sector->Lines) @@ -634,37 +634,37 @@ void DoomLevelMesh::CeilingHeightChanged(sector_t* sector) } } -void DoomLevelMesh::MidTex3DHeightChanged(sector_t* sector) +void DoomLevelMesh::OnMidTex3DHeightChanged(sector_t* sector) { // UpdateFlat(sector->Index(), SurfaceUpdateType::Full); } -void DoomLevelMesh::FloorTextureChanged(sector_t* sector) +void DoomLevelMesh::OnFloorTextureChanged(sector_t* sector) { UpdateFlat(sector->Index(), SurfaceUpdateType::Full); } -void DoomLevelMesh::CeilingTextureChanged(sector_t* sector) +void DoomLevelMesh::OnCeilingTextureChanged(sector_t* sector) { UpdateFlat(sector->Index(), SurfaceUpdateType::Full); } -void DoomLevelMesh::SectorChangedOther(sector_t* sector) +void DoomLevelMesh::OnSectorChangedOther(sector_t* sector) { UpdateFlat(sector->Index(), SurfaceUpdateType::Full); } -void DoomLevelMesh::SideTextureChanged(side_t* side, int section) +void DoomLevelMesh::OnSideTextureChanged(side_t* side, int section) { UpdateSide(side->Index(), SurfaceUpdateType::Full); } -void DoomLevelMesh::SideDecalsChanged(side_t* side) +void DoomLevelMesh::OnSideDecalsChanged(side_t* side) { UpdateSide(side->Index(), SurfaceUpdateType::Full); } -void DoomLevelMesh::SectorLightChanged(sector_t* sector) +void DoomLevelMesh::OnSectorLightChanged(sector_t* sector) { UpdateFlat(sector->Index(), SurfaceUpdateType::LightsOnly); for (line_t* line : sector->Lines) @@ -676,11 +676,11 @@ void DoomLevelMesh::SectorLightChanged(sector_t* sector) } } -void DoomLevelMesh::SectorLightThinkerCreated(sector_t* sector, DLighting* lightthinker) +void DoomLevelMesh::OnSectorLightThinkerCreated(sector_t* sector, DLighting* lightthinker) { } -void DoomLevelMesh::SectorLightThinkerDestroyed(sector_t* sector, DLighting* lightthinker) +void DoomLevelMesh::OnSectorLightThinkerDestroyed(sector_t* sector, DLighting* lightthinker) { } diff --git a/src/rendering/hwrenderer/doom_levelmesh.h b/src/rendering/hwrenderer/doom_levelmesh.h index b1271fa10..d8a15d0c5 100644 --- a/src/rendering/hwrenderer/doom_levelmesh.h +++ b/src/rendering/hwrenderer/doom_levelmesh.h @@ -113,17 +113,17 @@ public: void DeleteLightmapLump(FLevelLocals& doomMap); static FString GetMapFilename(FLevelLocals& doomMap); - void FloorHeightChanged(sector_t* sector) override; - void CeilingHeightChanged(sector_t* sector) override; - void MidTex3DHeightChanged(sector_t* sector) override; - void FloorTextureChanged(sector_t* sector) override; - void CeilingTextureChanged(sector_t* sector) override; - void SectorChangedOther(sector_t* sector) override; - void SideTextureChanged(side_t* side, int section) override; - void SideDecalsChanged(side_t* side) override; - void SectorLightChanged(sector_t* sector) override; - void SectorLightThinkerCreated(sector_t* sector, DLighting* lightthinker) override; - void SectorLightThinkerDestroyed(sector_t* sector, DLighting* lightthinker) override; + void OnFloorHeightChanged(sector_t* sector) override; + void OnCeilingHeightChanged(sector_t* sector) override; + void OnMidTex3DHeightChanged(sector_t* sector) override; + void OnFloorTextureChanged(sector_t* sector) override; + void OnCeilingTextureChanged(sector_t* sector) override; + void OnSectorChangedOther(sector_t* sector) override; + void OnSideTextureChanged(side_t* side, int section) override; + void OnSideDecalsChanged(side_t* side) override; + void OnSectorLightChanged(sector_t* sector) override; + void OnSectorLightThinkerCreated(sector_t* sector, DLighting* lightthinker) override; + void OnSectorLightThinkerDestroyed(sector_t* sector, DLighting* lightthinker) override; void Reset(const LevelMeshLimits& limits) override {