mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2025-02-27 05:30:56 +00:00
- made the MapSectionGenerator a class to remove a global array.
This commit is contained in:
parent
4357f0dc40
commit
202d209eb8
1 changed files with 133 additions and 119 deletions
|
@ -51,156 +51,169 @@
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
//
|
// Map section generation
|
||||||
|
// Map sections are physically separated parts of the map.
|
||||||
|
// If the player is in section A, any map part in other sections can
|
||||||
|
// often be quickly discarded to improve performance.
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
static TArray<subsector_t *> MapSectionCollector;
|
|
||||||
|
|
||||||
static void DoSetMapSection(subsector_t *sub, int num)
|
struct MapSectionGenerator
|
||||||
{
|
{
|
||||||
MapSectionCollector.Resize(1);
|
struct cvertex_t
|
||||||
MapSectionCollector[0] = sub;
|
|
||||||
sub->mapsection = num;
|
|
||||||
for (unsigned a = 0; a < MapSectionCollector.Size(); a++)
|
|
||||||
{
|
{
|
||||||
sub = MapSectionCollector[a];
|
double X, Y;
|
||||||
for (uint32_t i = 0; i < sub->numlines; i++)
|
|
||||||
|
operator int() const { return xs_FloorToInt(X) + 65536 * xs_FloorToInt(Y); }
|
||||||
|
bool operator!= (const cvertex_t &other) const { return fabs(X - other.X) >= EQUAL_EPSILON || fabs(Y - other.Y) >= EQUAL_EPSILON; }
|
||||||
|
cvertex_t& operator =(const vertex_t *v) { X = v->fX(); Y = v->fY(); return *this; }
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef TMap<cvertex_t, int> FSectionVertexMap;
|
||||||
|
TArray<subsector_t *> MapSectionCollector;
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void DoSetMapSection(subsector_t *sub, int num)
|
||||||
|
{
|
||||||
|
MapSectionCollector.Resize(1);
|
||||||
|
MapSectionCollector[0] = sub;
|
||||||
|
sub->mapsection = num;
|
||||||
|
for (unsigned a = 0; a < MapSectionCollector.Size(); a++)
|
||||||
{
|
{
|
||||||
seg_t * seg = sub->firstline + i;
|
sub = MapSectionCollector[a];
|
||||||
|
for (uint32_t i = 0; i < sub->numlines; i++)
|
||||||
if (seg->PartnerSeg)
|
|
||||||
{
|
{
|
||||||
subsector_t * sub2 = seg->PartnerSeg->Subsector;
|
seg_t * seg = sub->firstline + i;
|
||||||
|
|
||||||
if (sub2->mapsection != num)
|
if (seg->PartnerSeg)
|
||||||
{
|
{
|
||||||
assert(sub2->mapsection == 0);
|
subsector_t * sub2 = seg->PartnerSeg->Subsector;
|
||||||
sub2->mapsection = num;
|
|
||||||
MapSectionCollector.Push(sub2);
|
if (sub2->mapsection != num)
|
||||||
|
{
|
||||||
|
assert(sub2->mapsection == 0);
|
||||||
|
sub2->mapsection = num;
|
||||||
|
MapSectionCollector.Push(sub2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
MapSectionCollector.Clear();
|
||||||
}
|
}
|
||||||
MapSectionCollector.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Merge sections. This is needed in case the map contains errors
|
// Merge sections. This is needed in case the map contains errors
|
||||||
// like overlapping lines resulting in abnormal subsectors.
|
// like overlapping lines resulting in abnormal subsectors.
|
||||||
//
|
//
|
||||||
// This function ensures that any vertex position can only be in one section.
|
// This function ensures that any vertex position can only be in one section.
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
struct cvertex_t
|
|
||||||
{
|
|
||||||
double X, Y;
|
|
||||||
|
|
||||||
operator int() const { return xs_FloorToInt(X) + 65536 * xs_FloorToInt(Y); }
|
int MergeMapSections(int num)
|
||||||
bool operator!= (const cvertex_t &other) const { return fabs(X - other.X) >= EQUAL_EPSILON || fabs(Y - other.Y) >= EQUAL_EPSILON; }
|
|
||||||
cvertex_t& operator =(const vertex_t *v) { X = v->fX(); Y = v->fY(); return *this; }
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef TMap<cvertex_t, int> FSectionVertexMap;
|
|
||||||
|
|
||||||
static int MergeMapSections(int num)
|
|
||||||
{
|
|
||||||
FSectionVertexMap vmap;
|
|
||||||
FSectionVertexMap::Pair *pair;
|
|
||||||
TArray<int> sectmap;
|
|
||||||
TArray<bool> sectvalid;
|
|
||||||
sectmap.Resize(num);
|
|
||||||
sectvalid.Resize(num);
|
|
||||||
for (int i = 0; i < num; i++)
|
|
||||||
{
|
{
|
||||||
sectmap[i] = -1;
|
FSectionVertexMap vmap;
|
||||||
sectvalid[i] = true;
|
FSectionVertexMap::Pair *pair;
|
||||||
}
|
TArray<int> sectmap;
|
||||||
int mergecount = 1;
|
TArray<bool> sectvalid;
|
||||||
|
sectmap.Resize(num);
|
||||||
|
sectvalid.Resize(num);
|
||||||
cvertex_t vt;
|
for (int i = 0; i < num; i++)
|
||||||
|
|
||||||
// first step: Set mapsection for all vertex positions.
|
|
||||||
for (auto &seg : level.segs)
|
|
||||||
{
|
|
||||||
int section = seg.Subsector->mapsection;
|
|
||||||
for (int j = 0; j < 2; j++)
|
|
||||||
{
|
{
|
||||||
vt = j == 0 ? seg.v1 : seg.v2;
|
sectmap[i] = -1;
|
||||||
vmap[vt] = section;
|
sectvalid[i] = true;
|
||||||
}
|
}
|
||||||
}
|
int mergecount = 1;
|
||||||
|
|
||||||
// second step: Check if any seg references more than one mapsection, either by subsector or by vertex
|
|
||||||
for (auto &seg : level.segs)
|
cvertex_t vt;
|
||||||
{
|
|
||||||
int section = seg.Subsector->mapsection;
|
// first step: Set mapsection for all vertex positions.
|
||||||
for (int j = 0; j < 2; j++)
|
for (auto &seg : level.segs)
|
||||||
{
|
{
|
||||||
vt = j == 0 ? seg.v1 : seg.v2;
|
int section = seg.Subsector->mapsection;
|
||||||
int vsection = vmap[vt];
|
for (int j = 0; j < 2; j++)
|
||||||
|
|
||||||
if (vsection != section)
|
|
||||||
{
|
{
|
||||||
// These 2 sections should be merged
|
vt = j == 0 ? seg.v1 : seg.v2;
|
||||||
for (auto &sub : level.subsectors)
|
vmap[vt] = section;
|
||||||
{
|
|
||||||
if (sub.mapsection == vsection) sub.mapsection = section;
|
|
||||||
}
|
|
||||||
FSectionVertexMap::Iterator it(vmap);
|
|
||||||
while (it.NextPair(pair))
|
|
||||||
{
|
|
||||||
if (pair->Value == vsection) pair->Value = section;
|
|
||||||
}
|
|
||||||
sectvalid[vsection - 1] = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
for (int i = 0; i < num; i++)
|
|
||||||
{
|
|
||||||
if (sectvalid[i]) sectmap[i] = mergecount++;
|
|
||||||
}
|
|
||||||
for (auto &sub : level.subsectors)
|
|
||||||
{
|
|
||||||
sub.mapsection = sectmap[sub.mapsection - 1];
|
|
||||||
assert(sub.mapsection != -1);
|
|
||||||
}
|
|
||||||
return mergecount - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
// second step: Check if any seg references more than one mapsection, either by subsector or by vertex
|
||||||
//
|
for (auto &seg : level.segs)
|
||||||
//
|
{
|
||||||
//
|
int section = seg.Subsector->mapsection;
|
||||||
//==========================================================================
|
for (int j = 0; j < 2; j++)
|
||||||
|
{
|
||||||
|
vt = j == 0 ? seg.v1 : seg.v2;
|
||||||
|
int vsection = vmap[vt];
|
||||||
|
|
||||||
static void SetMapSections()
|
if (vsection != section)
|
||||||
{
|
{
|
||||||
bool set;
|
// These 2 sections should be merged
|
||||||
int num = 0;
|
for (auto &sub : level.subsectors)
|
||||||
do
|
{
|
||||||
{
|
if (sub.mapsection == vsection) sub.mapsection = section;
|
||||||
set = false;
|
}
|
||||||
|
FSectionVertexMap::Iterator it(vmap);
|
||||||
|
while (it.NextPair(pair))
|
||||||
|
{
|
||||||
|
if (pair->Value == vsection) pair->Value = section;
|
||||||
|
}
|
||||||
|
sectvalid[vsection - 1] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < num; i++)
|
||||||
|
{
|
||||||
|
if (sectvalid[i]) sectmap[i] = mergecount++;
|
||||||
|
}
|
||||||
for (auto &sub : level.subsectors)
|
for (auto &sub : level.subsectors)
|
||||||
{
|
{
|
||||||
if (sub.mapsection == 0)
|
sub.mapsection = sectmap[sub.mapsection - 1];
|
||||||
|
assert(sub.mapsection != -1);
|
||||||
|
}
|
||||||
|
return mergecount - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void SetMapSections()
|
||||||
|
{
|
||||||
|
bool set;
|
||||||
|
int num = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
set = false;
|
||||||
|
for (auto &sub : level.subsectors)
|
||||||
{
|
{
|
||||||
num++;
|
if (sub.mapsection == 0)
|
||||||
DoSetMapSection(&sub, num);
|
{
|
||||||
set = true;
|
num++;
|
||||||
break;
|
DoSetMapSection(&sub, num);
|
||||||
|
set = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
while (set);
|
||||||
|
num = MergeMapSections(num);
|
||||||
|
currentmapsection.Resize(1 + num/8);
|
||||||
|
#ifdef DEBUG
|
||||||
|
Printf("%d map sections found\n", num);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
while (set);
|
};
|
||||||
num = MergeMapSections(num);
|
|
||||||
currentmapsection.Resize(1 + num/8);
|
|
||||||
#ifdef DEBUG
|
|
||||||
Printf("%d map sections found\n", num);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -283,7 +296,8 @@ static void PrepareSectorData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetMapSections();
|
MapSectionGenerator msg;
|
||||||
|
msg.SetMapSections();
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
Loading…
Reference in a new issue