mirror of
https://github.com/ZDoom/Raze.git
synced 2025-04-07 00:11:22 +00:00
- reimplemented sector splitting.
With the new setup this is a lot easier than with the old one.
This commit is contained in:
parent
d46e3c87e0
commit
7c5080f654
3 changed files with 96 additions and 13 deletions
|
@ -18,7 +18,6 @@ struct SectionLine
|
|||
int endpoint;
|
||||
int wall;
|
||||
int partner;
|
||||
int point2index;
|
||||
|
||||
vec2_t v1() const { return ::wall[startpoint].pos; }
|
||||
vec2_t v2() const { return ::wall[endpoint].pos; }
|
||||
|
|
|
@ -518,6 +518,61 @@ static void GroupData(TArray<loopcollect>& collect, TArray<sectionbuildsector>&
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// handle explicit sector splits while we still have simple index arrays.
|
||||
// This operates on the generated sections
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void TrySplitLoop(sectionbuildsector& builder, int firstwall, int lastwall)
|
||||
{
|
||||
for (unsigned s = 0; s < builder.sections.Size(); s++)
|
||||
{
|
||||
auto& section = builder.sections[s];
|
||||
if (section.loops.Size() > 1)
|
||||
{
|
||||
// Must have one loop to split a section. Should this ever be needed for sections with holes the loops need to be joined before running this.
|
||||
Printf("Unable to split sector %d between walls %d and %d\n", builder.sectnum, firstwall, lastwall);
|
||||
return;
|
||||
}
|
||||
auto& loop = section.loops[0];
|
||||
unsigned i1 = loop.Find(firstwall);
|
||||
unsigned i2 = loop.Find(lastwall);
|
||||
if (i1 >= loop.Size() || i2 >= loop.Size()) continue;
|
||||
if (i2 < i1) std::swap(i1, i2);
|
||||
TArray<int> newloop1;
|
||||
TArray<int> newloop2;
|
||||
auto it = loop.begin();
|
||||
auto end = loop.end() - 1;
|
||||
while (it != end && *it != firstwall) newloop1.Push(*it++);
|
||||
newloop1.Push(-firstwall);
|
||||
while (it != end && *it != lastwall) newloop2.Push(*it++);
|
||||
newloop2.Push(-lastwall);
|
||||
while (it != end) newloop1.Push(*it++);
|
||||
section.wallcount = newloop1.Size();
|
||||
newloop1.Push(loop.Last());
|
||||
section.loops[0] = std::move(newloop1);
|
||||
builder.sections.Reserve(1);
|
||||
auto& newsect = builder.sections.Last();
|
||||
newsect.bugged = false;
|
||||
newsect.wallcount = newloop2.Size();
|
||||
newloop2.Push(loop.Last());
|
||||
newsect.loops.Resize(1);
|
||||
newsect.loops[0] = std::move(newloop2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void SplitLoops(TArray<sectionbuildsector>& builders)
|
||||
{
|
||||
for (unsigned i = 0; i < splits.Size(); i += 3)
|
||||
{
|
||||
int sector = splits[0];
|
||||
TrySplitLoop(builders[sector], splits[i + 1], splits[i + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -527,10 +582,17 @@ static void GroupData(TArray<loopcollect>& collect, TArray<sectionbuildsector>&
|
|||
static void ConstructSections(TArray<sectionbuildsector>& builders)
|
||||
{
|
||||
// count all sections and allocate the global buffers.
|
||||
TArray<int> splitwalls;
|
||||
|
||||
// Allocate all Section walls.
|
||||
sectionLines.Resize(numwalls);
|
||||
sectionLines.Resize(numwalls + splits.Size() * 2 / 3);
|
||||
|
||||
for (unsigned i = 0; i < splits.Size(); i++)
|
||||
{
|
||||
if (i % 3) splitwalls.Push(splits[i]);
|
||||
}
|
||||
|
||||
int nextwall = numwalls;
|
||||
for (int i = 0; i < numwalls; i++)
|
||||
{
|
||||
sectionLines[i].startpoint = i;
|
||||
|
@ -538,6 +600,14 @@ static void ConstructSections(TArray<sectionbuildsector>& builders)
|
|||
sectionLines[i].wall = i;
|
||||
sectionLines[i].partner = wall[i].nextwall;
|
||||
}
|
||||
for (int i = numwalls; i < (int)sectionLines.Size(); i++)
|
||||
{
|
||||
int pair = (i - numwalls);
|
||||
sectionLines[i].startpoint = splitwalls[pair];
|
||||
sectionLines[i].endpoint = splitwalls[pair ^ 1];
|
||||
sectionLines[i].wall = -1;
|
||||
sectionLines[i].partner = numwalls + (pair ^ 1);
|
||||
}
|
||||
|
||||
unsigned count = 0;
|
||||
// allocate as much as possible from the arena here.
|
||||
|
@ -584,15 +654,25 @@ static void ConstructSections(TArray<sectionbuildsector>& builders)
|
|||
{
|
||||
auto& srcloop = srcsect.loops[i];
|
||||
auto& loop = section->loops[i];
|
||||
unsigned numwalls = srcloop.Size() - 1;
|
||||
auto walls = (int*)sectionArena.Calloc(numwalls * sizeof(int));
|
||||
loop.walls.Set(walls, numwalls);
|
||||
for (unsigned w = 0; w < numwalls; w++)
|
||||
unsigned numsectionwalls = srcloop.Size() - 1;
|
||||
auto walls = (int*)sectionArena.Calloc(numsectionwalls * sizeof(int));
|
||||
loop.walls.Set(walls, numsectionwalls);
|
||||
for (unsigned w = 0; w < numsectionwalls; w++)
|
||||
{
|
||||
int wall_i = srcloop[w];
|
||||
auto wal = §ionLines[wall_i];
|
||||
section->lines[curwall++] = loop.walls[w] = wall_i;
|
||||
wal->section = section->index;
|
||||
if (wall_i >= 0)
|
||||
{
|
||||
auto wal = §ionLines[wall_i];
|
||||
section->lines[curwall++] = loop.walls[w] = wall_i;
|
||||
wal->section = section->index;
|
||||
}
|
||||
else
|
||||
{
|
||||
wall_i = numwalls + splitwalls.Find(-wall_i);
|
||||
auto wal = §ionLines[wall_i];
|
||||
section->lines[curwall++] = loop.walls[w] = wall_i;
|
||||
wal->section = section->index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -623,6 +703,7 @@ void hw_CreateSections2()
|
|||
|
||||
TArray<sectionbuildsector> builders(numsectors, true);
|
||||
GroupData(collect, builders);
|
||||
SplitLoops(builders);
|
||||
|
||||
ConstructSections(builders);
|
||||
}
|
||||
|
|
|
@ -221,7 +221,6 @@ int BunchDrawer::ClipLine(int aline, bool portal)
|
|||
return CL_Skip;
|
||||
}
|
||||
if (line >= 0 && blockwall[line]) return CL_Draw;
|
||||
auto wal = &wall[line];
|
||||
|
||||
// convert to clipper coordinates and clamp to valid range.
|
||||
int startAngle = startAngleBam.asbam();
|
||||
|
@ -256,7 +255,10 @@ int BunchDrawer::ClipLine(int aline, bool portal)
|
|||
return CL_Skip;
|
||||
}
|
||||
|
||||
if (cline->partner == -1 || (wal->cstat & CSTAT_WALL_1WAY) || CheckClip(wal))
|
||||
if (line < 0)
|
||||
return CL_Pass;
|
||||
|
||||
if (cline->partner == -1 || (wall[line].cstat & CSTAT_WALL_1WAY) || CheckClip(&wall[line]))
|
||||
{
|
||||
// one-sided
|
||||
if (!portal && !dontclip) clipper->AddClipRange(startAngle, endAngle);
|
||||
|
@ -442,7 +444,7 @@ int BunchDrawer::BunchInFront(FBunch* b1, FBunch* b2)
|
|||
// Find the wall in b1 that overlaps b2->startangle
|
||||
for (int i = b1->startline; i <= b1->endline; i++)
|
||||
{
|
||||
endang = ClipAngle(wall[i].point2);
|
||||
endang = ClipAngle(sectionLines[i].endpoint);
|
||||
if (endang.asbam() > anglecheck.asbam())
|
||||
{
|
||||
// found a line
|
||||
|
@ -468,7 +470,7 @@ int BunchDrawer::BunchInFront(FBunch* b1, FBunch* b2)
|
|||
// Find the wall in b2 that overlaps b1->startangle
|
||||
for (int i = b2->startline; i <= b2->endline; i++)
|
||||
{
|
||||
endang = ClipAngle(wall[i].point2);
|
||||
endang = ClipAngle(sectionLines[i].endpoint);
|
||||
if (endang.asbam() > anglecheck.asbam())
|
||||
{
|
||||
// found a line
|
||||
|
@ -622,6 +624,7 @@ void BunchDrawer::ProcessSection(int sectionnum, bool portal)
|
|||
{
|
||||
if (walang1.asbam() >= angrange.asbam()) { walang1 = bamang(0); inbunch = false; }
|
||||
if (walang2.asbam() >= angrange.asbam()) walang2 = angrange;
|
||||
if (section->lines[i] >= numwalls) inbunch = false;
|
||||
if (!inbunch)
|
||||
{
|
||||
//Printf("Starting bunch:\n\tWall %d\n", section->lines[i]);
|
||||
|
|
Loading…
Reference in a new issue