diff --git a/source/core/maptypes.h b/source/core/maptypes.h index a6df03b7a..5a7b915c8 100644 --- a/source/core/maptypes.h +++ b/source/core/maptypes.h @@ -34,6 +34,8 @@ Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms #include "binaryangle.h" #include "dobject.h" +void MarkVerticesForSector(int sector); + //============================================================================= // // Constants @@ -222,30 +224,12 @@ struct sectortype int32_t ceilingz; int32_t floorz; - void setceilingz(int cc, bool temp = false) - { - ceilingz = cc; - } - void setfloorz(int cc, bool temp = false) - { - floorz = cc; - } - void addceilingz(int cc, bool temp = false) - { - ceilingz += cc; - } - void addfloorz(int cc, bool temp = false) - { - floorz += cc; - } - int32_t* ceilingzptr(bool temp = false) - { - return &ceilingz; - } - int32_t* floorzptr(bool temp = false) - { - return &floorz; - } + void setceilingz(int cc, bool temp = false); + void setfloorz(int cc, bool temp = false); + void addceilingz(int cc, bool temp = false); + void addfloorz(int cc, bool temp = false); + int32_t* ceilingzptr(bool temp = false); + int32_t* floorzptr(bool temp = false); #endif @@ -741,6 +725,40 @@ inline int walltype::Length() return length; } +#ifndef SECTOR_HACKJOB + +inline void sectortype::setceilingz(int cc, bool temp) +{ + ceilingz = cc; + if (!temp) MarkVerticesForSector(sector.IndexOf(this)); +} +inline void sectortype::setfloorz(int cc, bool temp) +{ + floorz = cc; + if (!temp) MarkVerticesForSector(sector.IndexOf(this)); +} +inline void sectortype::addceilingz(int cc, bool temp) +{ + ceilingz += cc; + if (!temp) MarkVerticesForSector(sector.IndexOf(this)); +} +inline void sectortype::addfloorz(int cc, bool temp) +{ + floorz += cc; + if (!temp) MarkVerticesForSector(sector.IndexOf(this)); +} +inline int32_t* sectortype::ceilingzptr(bool temp) +{ + if (!temp) MarkVerticesForSector(sector.IndexOf(this)); + return &ceilingz; +} +inline int32_t* sectortype::floorzptr(bool temp) +{ + if (!temp) MarkVerticesForSector(sector.IndexOf(this)); + return &floorz; +} + +#endif //============================================================================= // // Map loader stuff diff --git a/source/core/rendering/hw_vertexmap.cpp b/source/core/rendering/hw_vertexmap.cpp index 2c4539755..71c355f68 100644 --- a/source/core/rendering/hw_vertexmap.cpp +++ b/source/core/rendering/hw_vertexmap.cpp @@ -43,6 +43,7 @@ extern FMemArena sectionArena; // allocate from the same arena as the section as TArray vertexMap; // maps walls to the vertex data. TArray vertices; +TArray> verticespersector; void CreateVertexMap() @@ -51,10 +52,13 @@ void CreateVertexMap() processed.Zero(); TArray walls; TArray sectors; + TArray countpersector(sector.Size(), true); vertices.Clear(); vertexMap.Resize(wall.Size()); + verticespersector.Resize(sector.Size()); + for (auto& c : countpersector) c = 0; for (unsigned i = 0; i < wall.Size(); i++) { if (processed[i]) continue; @@ -64,10 +68,14 @@ void CreateVertexMap() vertexscan(&wall[i], [&](walltype* wal) { int w = wallnum(wal); + if (processed[w]) return; // broken wall setups can trigger this. walls.Push(w); processed.Set(w); if (!sectors.Contains(wal->sector)) + { sectors.Push(wal->sector); + countpersector[wal->sector]++; + } }); vertices.Reserve(1); @@ -90,6 +98,47 @@ void CreateVertexMap() // 2x number of sectors is currently the upper bound for the number of associated heights. newvert->heightlist = (float*)sectionArena.Alloc(sectors.Size() * sizeof(float)); + + // create the inverse map to assign vertices to sectors. This is needed by the dirty marking code. + for (unsigned ii = 0; ii < sector.Size(); ii++) + { + auto sdata = (int*)sectionArena.Alloc(countpersector[ii] * sizeof(int)); + verticespersector[ii].Set(sdata, countpersector[ii]); + countpersector[ii] = 0; + } + for (unsigned ii = 0; ii < vertices.Size(); ii++) + { + for (auto sec : vertices[ii].sectors) + { + verticespersector[sec][countpersector[sec]++] = ii; + } + } + } +#if 0 + for (unsigned i = 0; i < vertices.Size(); i++) + { + Printf("Vertex %d at (%2.3f, %2.3f)\n", i, wall[vertices[i].masterwall].pos.X / 16., wall[vertices[i].masterwall].pos.Y / -16.); + Printf(" Walls: "); + for (auto wal : vertices[i].walls) Printf("%d ", wal); + Printf("\n"); + Printf(" Sectors: "); + for (auto wal : vertices[i].sectors) Printf("%d ", wal); + Printf("\n"); + } +#endif +} + +//========================================================================== +// +// +// +//========================================================================== + +void MarkVerticesForSector(int sector) +{ + for (auto vert : verticespersector[sector]) + { + vertices[vert].dirty = true; } } @@ -102,6 +151,8 @@ void CreateVertexMap() void vertex_t::RecalcVertexHeights() { numheights = 0; + dirty = false; + if (sectors.Size() == 1) return; // no need to bother for (auto& sect : sectors) { float heights[2]; @@ -126,7 +177,6 @@ void vertex_t::RecalcVertexHeights() } } if (numheights <= 2) numheights = 0; // is not in need of any special attention - dirty = false; } diff --git a/source/core/rendering/scene/hw_walls.cpp b/source/core/rendering/scene/hw_walls.cpp index 06ae87702..ade1c901c 100644 --- a/source/core/rendering/scene/hw_walls.cpp +++ b/source/core/rendering/scene/hw_walls.cpp @@ -32,6 +32,7 @@ #include "hw_renderstate.h" #include "hw_skydome.h" #include "hw_drawstructs.h" +#include "hw_vertexmap.h" #include "gamefuncs.h" #include "cmdlib.h" @@ -999,6 +1000,14 @@ void HWWall::Process(HWDrawInfo* di, walltype* wal, sectortype* frontsector, sec RenderStyle = STYLE_Translucent; texture = NULL; + if (gl_seamless) + { + auto v = &vertices[vertexMap[wallnum(wal)]]; + if (v->dirty) v->RecalcVertexHeights(); + v = &vertices[vertexMap[wal->point2]]; + if (v->dirty) v->RecalcVertexHeights(); + } + /* if (wal->linedef->special == Line_Horizon) {