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

View file

@ -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<FLinePortal*> linkedPortals; // only the linked portals, this is used to speed up looking for them in P_CollectConnectedGroups.
TArray<FSectorPortalGroup *> portalGroups;
TArray<FLinePortalSpan> linePortalSpans;
FSectionContainer sections;
int NumMapSections;
TArray<zone_t> Zones;

View file

@ -88,6 +88,7 @@ struct Group
TArray<GroupWork> groupedSections;
TMap<int, bool> sideMap;
TArray<WorkSectionLine*> segments;
TArray<int> subsectors;
};
class FSectionCreator
@ -531,12 +532,14 @@ public:
{
const double MAX_GROUP_DIST = 256;
TArray<GroupWork> build;
TArray<int> 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);
}

View file

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

View file

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

View file

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

View file

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