mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
- added a workaround for the 'cannot split a seg' error in the node builder: In order to prevent all segs from ending up on the same side it will now force the bogus seg onto the other side of the node - regardless of whether this is correct or not, because the most important thing here is that the set of segs gets split to prevent the node builder from ending up in an endless recursion trying to split the same set of data and endlessly failing.
Note that this is not a fix, it's merely a countermeasure to avoid the crash in ZPack's E2M6 which this seems to achieve.
This commit is contained in:
parent
1ed2a0baf9
commit
c8445703ac
1 changed files with 47 additions and 31 deletions
|
@ -818,41 +818,57 @@ void FNodeBuilder::SplitSegs (DWORD set, node_t &node, DWORD splitseg, DWORD &ou
|
|||
newvert.y += fixed_t(frac * double(Vertices[seg->v2].y - newvert.y));
|
||||
vertnum = VertexMap->SelectVertexClose (newvert);
|
||||
|
||||
if (vertnum == (unsigned int)seg->v1 || vertnum == (unsigned int)seg->v2)
|
||||
if (vertnum != (unsigned int)seg->v1 && vertnum != (unsigned int)seg->v2)
|
||||
{
|
||||
Printf("SelectVertexClose selected endpoint of seg %u\n", set);
|
||||
seg2 = SplitSeg(set, vertnum, sidev[0]);
|
||||
|
||||
Segs[seg2].next = outset0;
|
||||
outset0 = seg2;
|
||||
Segs[set].next = outset1;
|
||||
outset1 = set;
|
||||
_count0++;
|
||||
_count1++;
|
||||
|
||||
// Also split the seg on the back side
|
||||
if (Segs[set].partner != DWORD_MAX)
|
||||
{
|
||||
int partner1 = Segs[set].partner;
|
||||
int partner2 = SplitSeg(partner1, vertnum, sidev[1]);
|
||||
// The newly created seg stays in the same set as the
|
||||
// back seg because it has not been considered for splitting
|
||||
// yet. If it had been, then the front seg would have already
|
||||
// been split, and we would not be in this default case.
|
||||
// Moreover, the back seg may not even be in the set being
|
||||
// split, so we must not move its pieces into the out sets.
|
||||
Segs[partner1].next = partner2;
|
||||
Segs[partner2].partner = seg2;
|
||||
Segs[seg2].partner = partner2;
|
||||
}
|
||||
|
||||
if (GLNodes)
|
||||
{
|
||||
AddIntersection(node, vertnum);
|
||||
}
|
||||
}
|
||||
|
||||
seg2 = SplitSeg (set, vertnum, sidev[0]);
|
||||
|
||||
Segs[seg2].next = outset0;
|
||||
outset0 = seg2;
|
||||
Segs[set].next = outset1;
|
||||
outset1 = set;
|
||||
_count0++;
|
||||
_count1++;
|
||||
|
||||
// Also split the seg on the back side
|
||||
if (Segs[set].partner != DWORD_MAX)
|
||||
else
|
||||
{
|
||||
int partner1 = Segs[set].partner;
|
||||
int partner2 = SplitSeg (partner1, vertnum, sidev[1]);
|
||||
// The newly created seg stays in the same set as the
|
||||
// back seg because it has not been considered for splitting
|
||||
// yet. If it had been, then the front seg would have already
|
||||
// been split, and we would not be in this default case.
|
||||
// Moreover, the back seg may not even be in the set being
|
||||
// split, so we must not move its pieces into the out sets.
|
||||
Segs[partner1].next = partner2;
|
||||
Segs[partner2].partner = seg2;
|
||||
Segs[seg2].partner = partner2;
|
||||
// all that matters here is to prevent a crash so we must make sure that we do not end up with all segs being sorted to the same side - even if this may not be correct.
|
||||
// But if we do not do that this code would not be able to move on. Just discarding the seg is also not an option because it won't guarantee that we achieve an actual split.
|
||||
if (_count0 == 0)
|
||||
{
|
||||
side = 0;
|
||||
seg->next = outset0;
|
||||
outset0 = set;
|
||||
_count0++;
|
||||
}
|
||||
else
|
||||
{
|
||||
side = 1;
|
||||
seg->next = outset1;
|
||||
outset1 = set;
|
||||
_count1++;
|
||||
}
|
||||
}
|
||||
|
||||
if (GLNodes)
|
||||
{
|
||||
AddIntersection (node, vertnum);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
if (side >= 0 && GLNodes)
|
||||
|
|
Loading…
Reference in a new issue