- automatically create sections and store them with the level data.

- added subsector indexing to sections.

This is needed for finding a section from a point.
This commit is contained in:
Christoph Oelckers 2018-11-04 22:19:11 +01:00
parent 49bfdbef9f
commit 0deb388a75
7 changed files with 44 additions and 10 deletions

View File

@ -1083,6 +1083,7 @@ public:
FBlockNode *BlockNode; // links in blocks (if needed) FBlockNode *BlockNode; // links in blocks (if needed)
struct sector_t *Sector; struct sector_t *Sector;
subsector_t * subsector; subsector_t * subsector;
FSection * section;
double floorz, ceilingz; // closest together of contacted secs double floorz, ceilingz; // closest together of contacted secs
double dropoffz; // killough 11/98: the lowest floor over all contacted Sectors. double dropoffz; // killough 11/98: the lowest floor over all contacted Sectors.

View File

@ -42,6 +42,7 @@
#include "p_blockmap.h" #include "p_blockmap.h"
#include "p_local.h" #include "p_local.h"
#include "p_destructible.h" #include "p_destructible.h"
#include "hwrenderer/data/hw_sections.h"
struct FLevelLocals struct FLevelLocals
{ {
@ -94,6 +95,8 @@ struct FLevelLocals
TArray<FLinePortal*> linkedPortals; // only the linked portals, this is used to speed up looking for them in P_CollectConnectedGroups. TArray<FLinePortal*> linkedPortals; // only the linked portals, this is used to speed up looking for them in P_CollectConnectedGroups.
TArray<FSectorPortalGroup *> portalGroups; TArray<FSectorPortalGroup *> portalGroups;
TArray<FLinePortalSpan> linePortalSpans; TArray<FLinePortalSpan> linePortalSpans;
FSectionContainer sections;
int NumMapSections; int NumMapSections;
TArray<zone_t> Zones; TArray<zone_t> Zones;

View File

@ -88,6 +88,7 @@ struct Group
TArray<GroupWork> groupedSections; TArray<GroupWork> groupedSections;
TMap<int, bool> sideMap; TMap<int, bool> sideMap;
TArray<WorkSectionLine*> segments; TArray<WorkSectionLine*> segments;
TArray<int> subsectors;
}; };
class FSectionCreator class FSectionCreator
@ -531,12 +532,14 @@ public:
{ {
const double MAX_GROUP_DIST = 256; const double MAX_GROUP_DIST = 256;
TArray<GroupWork> build; TArray<GroupWork> build;
TArray<int> subsectorcopy;
if (workingSet.Size() == 1) if (workingSet.Size() == 1)
{ {
groupForSection[workingSet[0].index] = groups.Size(); groupForSection[workingSet[0].index] = groups.Size();
Group g; Group g;
g.groupedSections = std::move(workingSet); g.groupedSections = std::move(workingSet);
g.subsectors = std::move(rawsections[workingSet[0].index]);
groups.Push(std::move(g)); groups.Push(std::move(g));
return; return;
} }
@ -546,8 +549,10 @@ public:
build.Clear(); build.Clear();
build.Push(workingSet[0]); build.Push(workingSet[0]);
groupForSection[workingSet[0].index] = groups.Size(); groupForSection[workingSet[0].index] = groups.Size();
subsectorcopy = std::move(rawsections[workingSet[0].index]);
workingSet.Delete(0); workingSet.Delete(0);
// Don't use iterators here. These arrays are modified inside. // Don't use iterators here. These arrays are modified inside.
for (unsigned j = 0; j < build.Size(); j++) for (unsigned j = 0; j < build.Size(); j++)
{ {
@ -560,6 +565,7 @@ public:
{ {
build.Push(workingSet[i]); build.Push(workingSet[i]);
groupForSection[workingSet[i].index] = groups.Size(); groupForSection[workingSet[i].index] = groups.Size();
subsectorcopy.Append(rawsections[workingSet[i].index]);
workingSet.Delete(i); workingSet.Delete(i);
i--; i--;
continue; continue;
@ -570,6 +576,7 @@ public:
{ {
build.Push(workingSet[i]); build.Push(workingSet[i]);
groupForSection[workingSet[i].index] = groups.Size(); groupForSection[workingSet[i].index] = groups.Size();
subsectorcopy.Append(rawsections[workingSet[i].index]);
workingSet.Delete(i); workingSet.Delete(i);
i--; i--;
continue; continue;
@ -578,6 +585,7 @@ public:
} }
Group g; Group g;
g.groupedSections = std::move(build); g.groupedSections = std::move(build);
g.subsectors = std::move(subsectorcopy);
groups.Push(std::move(g)); groups.Push(std::move(g));
} }
} }
@ -615,6 +623,7 @@ public:
output.allIndices.Resize(level.subsectors.Size() + level.sides.Size()); output.allIndices.Resize(level.subsectors.Size() + level.sides.Size());
output.sectionForSubsectorPtr = &output.allIndices[0]; output.sectionForSubsectorPtr = &output.allIndices[0];
output.sectionForSidedefPtr = &output.allIndices[level.subsectors.Size()]; output.sectionForSidedefPtr = &output.allIndices[level.subsectors.Size()];
memset(output.sectionForSubsectorPtr, -1, sizeof(int) * level.subsectors.Size());
unsigned numsegments = 0; unsigned numsegments = 0;
unsigned numsides = 0; unsigned numsides = 0;
@ -642,9 +651,11 @@ public:
} }
output.allLines.Resize(numsegments); output.allLines.Resize(numsegments);
output.allSides.Resize(numsides); output.allSides.Resize(numsides);
output.allSubsectors.Resize(level.subsectors.Size());
numsegments = 0; numsegments = 0;
numsides = 0; numsides = 0;
unsigned numsubsectors = 0;
// Now piece it all together // Now piece it all together
unsigned curgroup = 0; unsigned curgroup = 0;
@ -658,6 +669,7 @@ public:
dest.validcount = 0; dest.validcount = 0;
dest.segments.Set(&output.allLines[numsegments], group.segments.Size()); dest.segments.Set(&output.allLines[numsegments], group.segments.Size());
dest.sides.Set(&output.allSides[numsides], group.sideMap.CountUsed()); dest.sides.Set(&output.allSides[numsides], group.sideMap.CountUsed());
dest.subsectors.Set(&output.allSubsectors[numsubsectors]);
dest.bounds = {1e32, 1e32, -1e32, -1e32}; dest.bounds = {1e32, 1e32, -1e32, -1e32};
numsegments += group.segments.Size(); numsegments += group.segments.Size();
@ -677,7 +689,14 @@ public:
while (it.NextPair(pair)) while (it.NextPair(pair))
{ {
output.allSides[numsides++] = &level.sides[pair->Key]; 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++; 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; FSectionCreator creat;
creat.GroupSubsectors(); creat.GroupSubsectors();
creat.CompileSections(); creat.CompileSections();
@ -753,12 +768,9 @@ void MakeSections()
creat.FindOuterLoops(); creat.FindOuterLoops();
creat.GroupSections(); creat.GroupSections();
creat.ConstructOutput(container); creat.ConstructOutput(container);
timer.Unclock();
PrintSections(container);
Printf("Time = %2.3f ms\n", timer.TimeMS());
} }
CCMD(makesections) CCMD(printsections)
{ {
MakeSections(); PrintSections(level.sections);
} }

View File

@ -2,9 +2,19 @@
#ifndef __GL_SECTIONS_H #ifndef __GL_SECTIONS_H
#define __GL_SECTIONS_H #define __GL_SECTIONS_H
#include <algorithm>
#include "tarray.h" #include "tarray.h"
#include "r_defs.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. // 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<FSectionLine> segments; TArrayView<FSectionLine> segments;
TArrayView<side_t *> 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<side_t *> 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<subsector_t *> 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; sector_t *sector;
FLightNode *lighthead; // Light nodes (blended and additive) FLightNode *lighthead; // Light nodes (blended and additive)
BoundingRect bounds; BoundingRect bounds;
@ -86,6 +97,7 @@ public:
TArray<FSection> allSections; TArray<FSection> allSections;
//TArray<vertex_t*> allVertices; //TArray<vertex_t*> allVertices;
TArray<side_t *> allSides; TArray<side_t *> allSides;
TArray<subsector_t *> allSubsectors;
TArray<int> allIndices; TArray<int> allIndices;
int *sectionForSubsectorPtr; // stored inside allIndices int *sectionForSubsectorPtr; // stored inside allIndices
@ -123,4 +135,6 @@ public:
}; };
void CreateSections(FSectionContainer &container);
#endif #endif

View File

@ -470,6 +470,7 @@ void AActor::LinkToWorld(FLinkContext *ctx, bool spawningmapthing, sector_t *sec
Sector = sector; Sector = sector;
subsector = R_PointInSubsector(Pos()); // this is from the rendering nodes, not the gameplay nodes! subsector = R_PointInSubsector(Pos()); // this is from the rendering nodes, not the gameplay nodes!
section = level.sections.SectionForSubsector(subsector->Index());
if (!(flags & MF_NOSECTOR)) if (!(flags & MF_NOSECTOR))
{ {

View File

@ -3559,6 +3559,7 @@ void P_FreeLevelData ()
FBehavior::StaticUnloadModules (); FBehavior::StaticUnloadModules ();
level.sections.Clear();
level.segs.Clear(); level.segs.Clear();
level.sectors.Clear(); level.sectors.Clear();
level.lines.Clear(); level.lines.Clear();

View File

@ -532,6 +532,8 @@ static void PrepareSegs()
void InitRenderInfo() void InitRenderInfo()
{ {
CreateSections(level.sections);
PrepareSegs(); PrepareSegs();
PrepareSectorData(); PrepareSectorData();
InitVertexData(); InitVertexData();