Hook up 3d floor updates to the level mesh

This commit is contained in:
Ricardo Luís Vaz Silva 2024-10-15 13:24:00 -03:00 committed by Magnus Norddahl
commit 44e69451cf
8 changed files with 153 additions and 44 deletions

View file

@ -1866,6 +1866,7 @@ void FLevelLocals::Init()
musicorder = info->musicorder;
MusicVolume = 1.f;
HasHeightSecs = false;
SecCorrelations.Clear();
LevelName = info->LookupLevelName();
NextMap = info->NextMap;

View file

@ -680,6 +680,8 @@ public:
bool HasDynamicLights; // Another render optimization for maps with no lights at all.
int frozenstate;
TMap<int, TArray<int>> 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.

View file

@ -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.

View file

@ -1,23 +1,103 @@
#include "levelmeshhelper.h"
#include "r_defs.h"
#include "g_levellocals.h"
#define PROPAGATE_CORRELATIONS_SECTOR(func)\
func(sector);\
TArray<int>* c = sector->Level->SecCorrelations.CheckKey(sector->Index());\
if(c) for(int index : *c) func(&sector->Level->sectors[index]);
#define PROPAGATE_CORRELATIONS_SECTOR2(func, arg2)\
func(sector, arg2);\
TArray<int>* c = sector->Level->SecCorrelations.CheckKey(sector->Index());\
if(c) for(int index : *c) func(&sector->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<int>* 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;

View file

@ -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;

View file

@ -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())

View file

@ -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)
{
}

View file

@ -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
{