- fixed: The node builder did not check if all segs could be split properly.

Also removed some fudging that tried to work around this case but produced
  a broken BSP tree on other maps.



SVN r2071 (trunk)
This commit is contained in:
Christoph Oelckers 2010-01-01 11:00:58 +00:00
parent 9aa1e20c77
commit bf7ed6258b
4 changed files with 94 additions and 7 deletions

View file

@ -1,3 +1,10 @@
January 1, 2010 (Changes by Graf Zahl)
- fixed: The node builder did not check if all segs could be split properly.
Also removed some fudging that tried to work around this case but produced
a broken BSP tree on other maps.
- Added Blzut3's Solaris patch.
- Fixed: Heretic's Weredragon (Beast) should not have a melee state.
January 1, 2010 (SBARINFO update) January 1, 2010 (SBARINFO update)
- Reorganized the SBarInfo code. - Reorganized the SBarInfo code.
- Added interpolate(<speed>) flag to drawnumber, drawbar, and drawgem. The old - Added interpolate(<speed>) flag to drawnumber, drawbar, and drawgem. The old
@ -6,10 +13,6 @@ January 1, 2010 (SBARINFO update)
- As an extension to the previous you can now use comparison operators on - As an extension to the previous you can now use comparison operators on
inventory items and armortype in drawswitchableimage. inventory items and armortype in drawswitchableimage.
January 1, 2010 (Changes by Graf Zahl)
- Added Blzut3's Solaris patch.
- Fixed: Heretic's Weredragon (Beast) should not have a melee state.
December 31, 2009 (Changes by Graf Zahl) December 31, 2009 (Changes by Graf Zahl)
- fixed: FastProjectile was missing all sky checks when the projectile's move - fixed: FastProjectile was missing all sky checks when the projectile's move
was blocked. was blocked.

View file

@ -114,6 +114,17 @@ int FNodeBuilder::CreateNode (DWORD set, fixed_t bbox[4])
DWORD set1, set2; DWORD set1, set2;
SplitSegs (set, node, splitseg, set1, set2); SplitSegs (set, node, splitseg, set1, set2);
// Check if the set could be split. It may happen that all segs end up on the same side
// in which case we need to create a subsector from such a set.
if (set1 == DWORD_MAX)
{
return 0x80000000 | CreateSubsector (set2, bbox);
}
else if (set2 == DWORD_MAX)
{
return 0x80000000 | CreateSubsector (set1, bbox);
}
D(PrintSet (1, set1)); D(PrintSet (1, set1));
D(Printf (PRINT_LOG, "(%d,%d) delta (%d,%d) from seg %d\n", node.x>>16, node.y>>16, node.dx>>16, node.dy>>16, splitseg)); D(Printf (PRINT_LOG, "(%d,%d) delta (%d,%d) from seg %d\n", node.x>>16, node.y>>16, node.dx>>16, node.dy>>16, splitseg));
D(PrintSet (2, set2)); D(PrintSet (2, set2));
@ -490,7 +501,9 @@ int FNodeBuilder::SelectSplitter (DWORD set, node_t &node, DWORD &splitseg, int
int FNodeBuilder::Heuristic (node_t &node, DWORD set, bool honorNoSplit) int FNodeBuilder::Heuristic (node_t &node, DWORD set, bool honorNoSplit)
{ {
int score = 0; int score = 1000000; // a high base so that segs that come too close to a splitter
// still can be weighed extremely negatively but preventing
// them from creating a negative score.
int segsInSet = 0; int segsInSet = 0;
int counts[2] = { 0, 0 }; int counts[2] = { 0, 0 };
int realSegs[2] = { 0, 0 }; int realSegs[2] = { 0, 0 };
@ -767,6 +780,27 @@ void FNodeBuilder::SplitSegs (DWORD set, node_t &node, DWORD splitseg, DWORD &ou
newvert.y += fixed_t(frac * double(Vertices[seg->v2].y - newvert.y)); newvert.y += fixed_t(frac * double(Vertices[seg->v2].y - newvert.y));
vertnum = VertexMap->SelectVertexClose (newvert); vertnum = VertexMap->SelectVertexClose (newvert);
if (vertnum == seg->v1 || vertnum == seg->v2)
{
// Check if the resulting split vertex matches one of the line's ends.
// In this case this seg must not be split
if ((vertnum == seg->v1 && sidev2 == -1) || (vertnum == seg->v2 && sidev1 == -1))
{
side = 0;
sidev1 = 0;
seg->next = outset0;
outset0 = set;
}
else
{
side = 1;
sidev2 = 0;
seg->next = outset1;
outset1 = set;
}
break;
}
seg2 = SplitSeg (set, vertnum, sidev1); seg2 = SplitSeg (set, vertnum, sidev1);
Segs[seg2].next = outset0; Segs[seg2].next = outset0;
@ -841,7 +875,7 @@ void FNodeBuilder::SplitSegs (DWORD set, node_t &node, DWORD splitseg, DWORD &ou
set = next; set = next;
} }
FixSplitSharers (node); FixSplitSharers (node);
if (GLNodes) if (GLNodes && outset0 != DWORD_MAX && outset1 != DWORD_MAX)
{ {
AddMinisegs (node, splitseg, outset0, outset1); AddMinisegs (node, splitseg, outset0, outset1);
} }

View file

@ -2712,6 +2712,7 @@ static void P_GroupLines (bool buildmap)
FBoundingBox bbox; FBoundingBox bbox;
bool flaggedNoFronts = false; bool flaggedNoFronts = false;
unsigned int ii, jj; unsigned int ii, jj;
TArray<int> nosector;
for (i = 0; i < (int)countof(times); ++i) for (i = 0; i < (int)countof(times); ++i)
{ {
@ -2722,7 +2723,13 @@ static void P_GroupLines (bool buildmap)
times[0].Clock(); times[0].Clock();
for (i = 0; i < numsubsectors; i++) for (i = 0; i < numsubsectors; i++)
{ {
subsectors[i].sector = segs[subsectors[i].firstline].sidedef->sector; side_t *side = segs[subsectors[i].firstline].sidedef;
if (side != NULL) subsectors[i].sector = side->sector;
else
{
subsectors[i].sector = NULL;
nosector.Push(i);
}
subsectors[i].validcount = validcount; subsectors[i].validcount = validcount;
double accumx = 0.0, accumy = 0.0; double accumx = 0.0, accumy = 0.0;
@ -2737,6 +2744,48 @@ static void P_GroupLines (bool buildmap)
subsectors[i].CenterX = fixed_t(accumx * 0.5 / subsectors[i].numlines); subsectors[i].CenterX = fixed_t(accumx * 0.5 / subsectors[i].numlines);
subsectors[i].CenterY = fixed_t(accumy * 0.5 / subsectors[i].numlines); subsectors[i].CenterY = fixed_t(accumy * 0.5 / subsectors[i].numlines);
} }
for(unsigned i=0;i<nosector.Size(); i++)
{
subsector_t *sub = &subsectors[nosector[i]];
for(unsigned j=0;j<sub->numlines; j++)
{
seg_t *seg = &segs[sub->firstline + j];
if (seg->frontsector != NULL)
{
sub->sector = seg->frontsector;
break;
}
if (seg->PartnerSeg != NULL && seg->PartnerSeg->backsector != NULL)
{
sub->sector = seg->PartnerSeg->backsector;
break;
}
}
// we still haven't found a matching sector. Check the back sides of this subsector's segs next
if (sub->sector == NULL)
{
for(unsigned j=0;j<sub->numlines; j++)
{
seg_t *seg = &segs[sub->firstline + j];
if (seg->backsector != NULL)
{
sub->sector = seg->backsector;
break;
}
if (seg->PartnerSeg != NULL && seg->PartnerSeg->frontsector != NULL)
{
sub->sector = seg->PartnerSeg->frontsector;
break;
}
}
}
if (sub->sector == NULL)
{
sub->sector = &sectors[0]; // prevent crashes. This hopefully does not matter because
// any subsector going through here is malformed.
Printf("Unable to assign a sector to subsector %d\n", subsectors[i].firstline);
}
}
times[0].Unclock(); times[0].Unclock();
// count number of lines in each sector // count number of lines in each sector

View file

@ -1026,6 +1026,7 @@ void R_Subsector (subsector_t *sub)
#endif #endif
frontsector = sub->sector; frontsector = sub->sector;
if (sub->sector == NULL) return;
frontsector->MoreFlags |= SECF_DRAWN; frontsector->MoreFlags |= SECF_DRAWN;
count = sub->numlines; count = sub->numlines;
line = &segs[sub->firstline]; line = &segs[sub->firstline];