mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-11 07:12:16 +00:00
- fixed: It may happen that a degenerate subsector ends up without any section or sector. Try to assign the best fit in such a case so that the relevant pointers are not null.
This commit is contained in:
parent
c946edd9bf
commit
094afdfd5f
2 changed files with 87 additions and 4 deletions
|
@ -184,6 +184,33 @@ public:
|
|||
{
|
||||
CompileSections(pair->Value, rawsections);
|
||||
}
|
||||
|
||||
// Make sure that all subsectors have a sector. In some degenerate cases a subsector may come up empty.
|
||||
// An example is in Doom.wad E3M4 near linedef 1087. With the grouping data here this is relatively easy to fix.
|
||||
sector_t *lastsector = &level.sectors[0];
|
||||
for (auto &rawsection : rawsections)
|
||||
{
|
||||
sector_t *mysector = nullptr;
|
||||
bool missing = false;
|
||||
for (auto num : rawsection)
|
||||
{
|
||||
auto &sub = level.subsectors[num];
|
||||
if (sub.sector == nullptr) missing = true;
|
||||
else mysector = sub.sector;
|
||||
}
|
||||
// Should the worst case happen and no sector be found, use the last used one. Subsectors must not be sector-less!
|
||||
if (mysector == nullptr) mysector = lastsector;
|
||||
else lastsector = mysector;
|
||||
for (auto num : rawsection)
|
||||
{
|
||||
auto &sub = level.subsectors[num];
|
||||
if (sub.sector == nullptr)
|
||||
{
|
||||
sub.sector = mysector;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
subsectormap.Clear();
|
||||
return rawsections;
|
||||
}
|
||||
|
@ -253,8 +280,7 @@ public:
|
|||
{
|
||||
MakeOutline(list, lineForSeg);
|
||||
}
|
||||
rawsections.Clear();
|
||||
rawsections.ShrinkToFit();
|
||||
rawsections.Reset();
|
||||
|
||||
// Assign partners after everything has been collected
|
||||
for (auto §ion : sections)
|
||||
|
@ -720,8 +746,59 @@ public:
|
|||
curgroup++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Check if some subsectors have come up empty on sections.
|
||||
// In this case assign the best fit from the containing sector.
|
||||
// This is only to ensure that the section pointer is not null.
|
||||
// These are always degenerate and do not produce any actual render output.
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void FixMissingReferences()
|
||||
{
|
||||
for (auto &sub : level.subsectors)
|
||||
{
|
||||
if (sub.section == nullptr)
|
||||
{
|
||||
int sector = sub.sector->Index();
|
||||
int mapsection = sub.mapsection;
|
||||
auto sections = level.sections.SectionsForSector(sector);
|
||||
FSection *bestfit = nullptr;
|
||||
for (auto §ion : sections)
|
||||
{
|
||||
if (bestfit == nullptr)
|
||||
{
|
||||
bestfit = §ion;
|
||||
}
|
||||
else if (bestfit->mapsection != section.mapsection && section.mapsection == mapsection)
|
||||
{
|
||||
bestfit = §ion;
|
||||
}
|
||||
else if (section.mapsection == mapsection)
|
||||
{
|
||||
BoundingRect rc;
|
||||
for (unsigned i = 0; i < sub.numlines; i++)
|
||||
{
|
||||
rc.addVertex(sub.firstline[i].v1->fX(), sub.firstline[i].v1->fY());
|
||||
rc.addVertex(sub.firstline[i].v2->fX(), sub.firstline[i].v2->fY());
|
||||
}
|
||||
// Pick the one closer to this subsector.
|
||||
if (rc.distanceTo(section.bounds) < rc.distanceTo(bestfit->bounds))
|
||||
{
|
||||
bestfit = §ion;
|
||||
}
|
||||
}
|
||||
}
|
||||
// This should really never happen, but better be safe than sorry and assign at least something.
|
||||
if (bestfit == nullptr) bestfit = &level.sections.allSections[0];
|
||||
sub.section = bestfit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
@ -787,6 +864,7 @@ void CreateSections(FSectionContainer &container)
|
|||
creat.FindOuterLoops();
|
||||
creat.GroupSections();
|
||||
creat.ConstructOutput(container);
|
||||
creat.FixMissingReferences();
|
||||
}
|
||||
|
||||
CCMD(printsections)
|
||||
|
|
|
@ -458,7 +458,12 @@ public:
|
|||
void Reset()
|
||||
{
|
||||
Clear();
|
||||
ShrinkToFit();
|
||||
Most = 0;
|
||||
if (Array != nullptr)
|
||||
{
|
||||
M_Free(Array);
|
||||
Array = nullptr;
|
||||
}
|
||||
}
|
||||
private:
|
||||
T *Array;
|
||||
|
|
Loading…
Reference in a new issue