From 8bbd90b200051fba0292088c3e9d61a269eb7f88 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 3 Jan 2010 01:03:44 +0000 Subject: [PATCH] - Merge latest ZDBSP changes into trunk. SVN r2094 (trunk) --- src/nodebuild.cpp | 31 +++++++++++++++++++++++++++++-- src/nodebuild.h | 3 +++ src/nodebuild_utility.cpp | 8 ++++---- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/nodebuild.cpp b/src/nodebuild.cpp index a988ba6e87..90aaff492e 100644 --- a/src/nodebuild.cpp +++ b/src/nodebuild.cpp @@ -490,7 +490,8 @@ int FNodeBuilder::SelectSplitter (DWORD set, node_t &node, DWORD &splitseg, int int FNodeBuilder::Heuristic (node_t &node, DWORD set, bool honorNoSplit) { - int score = 0; + // Set the initial score above 0 so that near vertex anti-weighting is less likely to produce a negative score. + int score = 1000000; int segsInSet = 0; int counts[2] = { 0, 0 }; int realSegs[2] = { 0, 0 }; @@ -596,7 +597,28 @@ int FNodeBuilder::Heuristic (node_t &node, DWORD set, bool honorNoSplit) frac = InterceptVector (node, *test); if (frac < 0.001 || frac > 0.999) { - score -= int(1 / frac); + FPrivVert *v1 = &Vertices[test->v1]; + FPrivVert *v2 = &Vertices[test->v2]; + double x = v1->x, y = v1->y; + x += frac * (v2->x - x); + y += frac * (v2->y - y); + if (fabs(x - v1->x) < VERTEX_EPSILON+1 && fabs(y - v1->y) < VERTEX_EPSILON+1) + { + D(Printf("Splitter will produce same start vertex as seg %d\n", i)); + return -1; + } + if (fabs(x - v2->x) < VERTEX_EPSILON+1 && fabs(y - v2->y) < VERTEX_EPSILON+1) + { + D(Printf("Splitter will produce same end vertex as seg %d\n", i)); + return -1; + } + if (frac > 0.999) + { + frac = 1 - frac; + } + int penalty = int(1 / frac); + score = MAX(score - penalty, 1); + D(Printf ("Penalized splitter by %d for being near endpt of seg %d (%f).\n", penalty, i, frac)); } counts[0]++; @@ -767,6 +789,11 @@ 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 == seg->v1 || vertnum == seg->v2) + { + Printf("SelectVertexClose selected endpoint of seg %u\n", set); + } + seg2 = SplitSeg (set, vertnum, sidev1); Segs[seg2].next = outset0; diff --git a/src/nodebuild.h b/src/nodebuild.h index d142a289b6..d0d59e7062 100644 --- a/src/nodebuild.h +++ b/src/nodebuild.h @@ -243,6 +243,9 @@ private: // Units are in fixed_ts. const double SIDE_EPSILON = 6.5536; +// Vertices within this distance of each other will be considered as the same vertex. +#define VERTEX_EPSILON 6 // This is a fixed_t value + inline int FNodeBuilder::PointOnSide (int x, int y, int x1, int y1, int dx, int dy) { // For most cases, a simple dot product is enough. diff --git a/src/nodebuild_utility.cpp b/src/nodebuild_utility.cpp index 3e50368cf8..a8a618b9ff 100644 --- a/src/nodebuild_utility.cpp +++ b/src/nodebuild_utility.cpp @@ -53,10 +53,6 @@ static const int PO_LINE_START = 1; static const int PO_LINE_EXPLICIT = 5; -// Vertices within this distance of each other vertically and horizontally -// will be considered as the same vertex. -const fixed_t VERTEX_EPSILON = 6; - #if 0 #define D(x) x #else @@ -555,8 +551,12 @@ int FNodeBuilder::FVertexMap::SelectVertexClose (FNodeBuilder::FPrivVert &vert) for (i = 0; i < block.Size(); ++i) { +#if VERTEX_EPSILON <= 1 + if (vertices[block[i]].x == vert.x && vertices[block[i]].y == vert.y) +#else if (abs(vertices[block[i]].x - vert.x) < VERTEX_EPSILON && abs(vertices[block[i]].y - vert.y) < VERTEX_EPSILON) +#endif { return block[i]; }