diff --git a/src/actor.h b/src/actor.h index 043da9b7ca..d87c51e98a 100644 --- a/src/actor.h +++ b/src/actor.h @@ -1083,6 +1083,7 @@ public: FBlockNode *BlockNode; // links in blocks (if needed) struct sector_t *Sector; subsector_t * subsector; + FSection * section; double floorz, ceilingz; // closest together of contacted secs double dropoffz; // killough 11/98: the lowest floor over all contacted Sectors. diff --git a/src/g_levellocals.h b/src/g_levellocals.h index dfdb6dbef6..6a42c12c5d 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -42,6 +42,7 @@ #include "p_blockmap.h" #include "p_local.h" #include "p_destructible.h" +#include "hwrenderer/data/hw_sections.h" struct FLevelLocals { @@ -94,6 +95,8 @@ struct FLevelLocals TArray linkedPortals; // only the linked portals, this is used to speed up looking for them in P_CollectConnectedGroups. TArray portalGroups; TArray linePortalSpans; + FSectionContainer sections; + int NumMapSections; TArray Zones; diff --git a/src/hwrenderer/data/hw_sections.cpp b/src/hwrenderer/data/hw_sections.cpp index 9364b9712b..e56736191a 100644 --- a/src/hwrenderer/data/hw_sections.cpp +++ b/src/hwrenderer/data/hw_sections.cpp @@ -88,6 +88,7 @@ struct Group TArray groupedSections; TMap sideMap; TArray segments; + TArray subsectors; }; class FSectionCreator @@ -531,12 +532,14 @@ public: { const double MAX_GROUP_DIST = 256; TArray build; + TArray subsectorcopy; if (workingSet.Size() == 1) { groupForSection[workingSet[0].index] = groups.Size(); Group g; g.groupedSections = std::move(workingSet); + g.subsectors = std::move(rawsections[workingSet[0].index]); groups.Push(std::move(g)); return; } @@ -546,8 +549,10 @@ public: build.Clear(); build.Push(workingSet[0]); groupForSection[workingSet[0].index] = groups.Size(); + subsectorcopy = std::move(rawsections[workingSet[0].index]); workingSet.Delete(0); + // Don't use iterators here. These arrays are modified inside. for (unsigned j = 0; j < build.Size(); j++) { @@ -560,6 +565,7 @@ public: { build.Push(workingSet[i]); groupForSection[workingSet[i].index] = groups.Size(); + subsectorcopy.Append(rawsections[workingSet[i].index]); workingSet.Delete(i); i--; continue; @@ -570,6 +576,7 @@ public: { build.Push(workingSet[i]); groupForSection[workingSet[i].index] = groups.Size(); + subsectorcopy.Append(rawsections[workingSet[i].index]); workingSet.Delete(i); i--; continue; @@ -578,6 +585,7 @@ public: } Group g; g.groupedSections = std::move(build); + g.subsectors = std::move(subsectorcopy); groups.Push(std::move(g)); } } @@ -615,6 +623,7 @@ public: output.allIndices.Resize(level.subsectors.Size() + level.sides.Size()); output.sectionForSubsectorPtr = &output.allIndices[0]; output.sectionForSidedefPtr = &output.allIndices[level.subsectors.Size()]; + memset(output.sectionForSubsectorPtr, -1, sizeof(int) * level.subsectors.Size()); unsigned numsegments = 0; unsigned numsides = 0; @@ -642,9 +651,11 @@ public: } output.allLines.Resize(numsegments); output.allSides.Resize(numsides); + output.allSubsectors.Resize(level.subsectors.Size()); numsegments = 0; numsides = 0; + unsigned numsubsectors = 0; // Now piece it all together unsigned curgroup = 0; @@ -658,6 +669,7 @@ public: dest.validcount = 0; dest.segments.Set(&output.allLines[numsegments], group.segments.Size()); dest.sides.Set(&output.allSides[numsides], group.sideMap.CountUsed()); + dest.subsectors.Set(&output.allSubsectors[numsubsectors]); dest.bounds = {1e32, 1e32, -1e32, -1e32}; numsegments += group.segments.Size(); @@ -677,7 +689,14 @@ public: while (it.NextPair(pair)) { output.allSides[numsides++] = &level.sides[pair->Key]; + output.sectionForSidedefPtr[pair->Key] = curgroup; } + memcpy(&output.allSubsectors[numsubsectors], &group.subsectors[0], group.subsectors.Size() * sizeof(subsector_t*)); + for (auto ssi : group.subsectors) + { + output.sectionForSubsectorPtr[ssi] = curgroup; + } + numsubsectors += group.subsectors.Size(); curgroup++; } } @@ -739,12 +758,8 @@ void PrintSections(FSectionContainer &container) // //============================================================================= -void MakeSections() +void CreateSections(FSectionContainer &container) { - FSectionContainer container; - cycle_t timer; - timer.Reset(); - timer.Clock(); FSectionCreator creat; creat.GroupSubsectors(); creat.CompileSections(); @@ -753,12 +768,9 @@ void MakeSections() creat.FindOuterLoops(); creat.GroupSections(); creat.ConstructOutput(container); - timer.Unclock(); - PrintSections(container); - Printf("Time = %2.3f ms\n", timer.TimeMS()); } -CCMD(makesections) +CCMD(printsections) { - MakeSections(); + PrintSections(level.sections); } \ No newline at end of file diff --git a/src/hwrenderer/data/hw_sections.h b/src/hwrenderer/data/hw_sections.h index 1cc6f2efa2..6edda1143d 100644 --- a/src/hwrenderer/data/hw_sections.h +++ b/src/hwrenderer/data/hw_sections.h @@ -2,9 +2,19 @@ #ifndef __GL_SECTIONS_H #define __GL_SECTIONS_H +#include #include "tarray.h" #include "r_defs.h" +// Undefine Windows garbage. +#ifdef min +#undef min +#endif + +#ifdef max +#undef max +#endif + //========================================================================== // // @@ -71,6 +81,7 @@ struct FSection // tbd: Do we need a list of subsectors here? Ideally the subsectors should not be used anywhere anymore except for finding out where a location is. TArrayView segments; TArrayView sides; // contains all sidedefs, including the internal ones that do not make up the outer shape. (this list is not exclusive. A sidedef can be in multiple sections!) + TArrayView subsectors; // contains all sidedefs, including the internal ones that do not make up the outer shape. (this list is not exclusive. A sidedef can be in multiple sections!) sector_t *sector; FLightNode *lighthead; // Light nodes (blended and additive) BoundingRect bounds; @@ -86,6 +97,7 @@ public: TArray allSections; //TArray allVertices; TArray allSides; + TArray allSubsectors; TArray allIndices; int *sectionForSubsectorPtr; // stored inside allIndices @@ -123,4 +135,6 @@ public: }; +void CreateSections(FSectionContainer &container); + #endif \ No newline at end of file diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index c94d80073f..19c9496d33 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -470,6 +470,7 @@ void AActor::LinkToWorld(FLinkContext *ctx, bool spawningmapthing, sector_t *sec Sector = sector; subsector = R_PointInSubsector(Pos()); // this is from the rendering nodes, not the gameplay nodes! + section = level.sections.SectionForSubsector(subsector->Index()); if (!(flags & MF_NOSECTOR)) { diff --git a/src/p_setup.cpp b/src/p_setup.cpp index d3ff4c4999..a204144efb 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -3559,6 +3559,7 @@ void P_FreeLevelData () FBehavior::StaticUnloadModules (); + level.sections.Clear(); level.segs.Clear(); level.sectors.Clear(); level.lines.Clear(); diff --git a/src/r_data/renderinfo.cpp b/src/r_data/renderinfo.cpp index bf59ec0c0a..f50c32d518 100644 --- a/src/r_data/renderinfo.cpp +++ b/src/r_data/renderinfo.cpp @@ -532,6 +532,8 @@ static void PrepareSegs() void InitRenderInfo() { + CreateSections(level.sections); + PrepareSegs(); PrepareSectorData(); InitVertexData();