Skip to content

Commit

Permalink
BSP Builder: Cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
danij-deng committed May 17, 2013
1 parent 0305d35 commit 518b2a5
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 76 deletions.
133 changes: 65 additions & 68 deletions doomsday/client/src/map/bsp/partitioner.cpp
Expand Up @@ -1233,11 +1233,11 @@ DENG2_PIMPL(Partitioner)
{
if(lineSeg->hasLeft())
{
lineSeg->left().setRight(&lineSeg->right());
lineSeg->left().setRight(lineSeg->hasRight()? &lineSeg->right() : 0);
}
if(lineSeg->hasRight())
{
lineSeg->right().setLeft(&lineSeg->left());
lineSeg->right().setLeft(lineSeg->hasLeft()? &lineSeg->left() : 0);
}

// Take ownership of and destroy the half-edge.
Expand Down Expand Up @@ -1585,10 +1585,8 @@ DENG2_PIMPL(Partitioner)
return center;
}

void clockwiseLeaf(BspLeaf &leaf, HEdgeSortBuffer &sortBuffer)
void clockwisePoly(Polygon &poly, HEdgeSortBuffer &sortBuffer)
{
Polygon &poly = leaf.poly();

Vector2d center = findPolyCenter(poly);
clockwiseOrder(poly, center, sortBuffer);

Expand Down Expand Up @@ -1657,100 +1655,99 @@ DENG2_PIMPL(Partitioner)
}

/**
* Sort all half-edges in each BSP leaf into a clockwise order.
* Sort the half-edges in each BSP leaf geometry into a clockwise order.
*
* @note This cannot be done during partitionSpace() as splitting a line
* segment with a twin will result in another half-edge being inserted into
* that twin's leaf (usually in the wrong place order-wise).
* that twin's leaf geometry (usually in the wrong place order-wise).
*/
void windLeafs()
{
HEdgeSortBuffer sortBuffer;
foreach(BspTreeNode *node, treeNodeMap)
{
if(!node->isLeaf()) continue;
BspLeaf *leaf = node->userData()->castTo<BspLeaf>();

// Sort the leaf's half-edges.
clockwiseLeaf(*leaf, sortBuffer);
BspLeaf *leaf = node->userData()->castTo<BspLeaf>();

// Add a twin half-edge for any which don't yet have one.
if(leaf->hasPoly())
{
HEdge *base = leaf->firstHEdge();
HEdge *hedge = base;
/*
* Finalize the built geometry.
*/
Polygon &geom = leaf->poly();
HEdge *base = geom.firstHEdge();

// Sort the half-edges.
clockwisePoly(geom, sortBuffer);

// Add a twin half-edge for any which don't yet have one.
HEdge *hedgeIt = base;
do
{
if(!hedge->hasTwin())
HEdge &hedge = *hedgeIt;
if(!hedge.hasTwin())
{
//DENG_ASSERT(&hedge->next() != hedge);
//DENG_ASSERT(&hedge->next().vertex() != &hedge->vertex());
hedge->_twin = new HEdge(hedge->next().vertex());
hedge->_twin->_twin = hedge;
//DENG_ASSERT(&hedge.next() != &hedge);
//DENG_ASSERT(&hedge.next().vertex() != &hedge.vertex());

hedge._twin = new HEdge(hedge.next().vertex());
hedge._twin->_twin = &hedge;

// There is now one more HEdge.
numHEdges += 1;
}
} while((hedge = &hedge->next()) != base);
}

/*
* Perform some post analysis on the built leaf.
*/
if(!sanityCheckHasRealHEdge(*leaf))
throw Error("Partitioner::clockwiseLeaf",
QString("BSP Leaf 0x%1 has no line-linked half-edge")
.arg(dintptr(leaf), 0, 16));
} while((hedgeIt = &hedgeIt->next()) != base);

// Look for migrant half-edges in the leaf.
if(Sector *sector = findFirstSectorInBspLeaf(*leaf))
{
HEdge *base = leaf->firstHEdge();
HEdge *hedge = base;
do
if(!sanityCheckHasRealHEdge(*leaf))
throw Error("Partitioner::windLeafs",
QString("BSP Leaf 0x%1 has no line-linked half-edge")
.arg(dintptr(leaf), 0, 16));

// Look for migrant half-edges in the wrong sector.
if(Sector *sector = findFirstSectorInBspLeaf(*leaf))
{
HEdge *hedgeIt = base;
do
{
HEdge &hedge = *hedgeIt;
LineSegment::Side const &lineSeg = lineSegment(hedge);
if(lineSeg.hasSector() && lineSeg.sectorPtr() != sector)
{
notifyMigrantHEdgeBuilt(hedge, *sector);
}

} while((hedgeIt = &hedgeIt->next()) != base);
}

// See if we built a partial leaf...
{
LineSegment::Side const &lineSeg = lineSegment(*hedge);
if(lineSeg.hasSector() && lineSeg.sectorPtr() != sector)
uint gaps = 0;
HEdge *hedgeIt = base;
do
{
notifyMigrantHEdgeBuilt(*hedge, *sector);
HEdge &hedge = *hedgeIt;

if(hedge.next().origin() != hedge.twin().origin())
{
gaps++;
}
} while((hedgeIt = &hedgeIt->next()) != base);

if(gaps > 0)
{
notifyPartialBspLeafBuilt(*leaf, gaps);
}
} while((hedge = &hedge->next()) != base);
}
}

leaf->setSector(chooseSectorForBspLeaf(*leaf));
if(!leaf->hasSector())
{
LOG_WARNING("BspLeaf %p is degenerate/orphan (%d HEdges).")
LOG_WARNING("BspLeaf %p is degenerate/orphan (%d half-edges).")
<< de::dintptr(leaf) << leaf->hedgeCount();
}

// See if we built a partial leaf...
uint gaps = 0;
HEdge const *base = leaf->firstHEdge();
HEdge const *hedge = base;
do
{
if(hedge->next().origin() != hedge->twin().origin())
{
gaps++;
}
} while((hedge = &hedge->next()) != base);

if(gaps > 0)
{
/*
HEdge const *base = leaf->firstHEdge();
HEdge const *hedge = base;
do
{
LOG_DEBUG(" half-edge %p %s -> %s")
<< de::dintptr(hedge)
<< hedge->origin().asText(),
<< hedge->twin().origin().asText();
} while((hedge = &hedge->next()) != base);
*/

notifyPartialBspLeafBuilt(*leaf, gaps);
}
}
}

Expand Down
26 changes: 18 additions & 8 deletions doomsday/client/src/map/gamemap.cpp
Expand Up @@ -92,9 +92,11 @@ DENG2_PIMPL(GameMap)
}
}

void collateBspLeafHEdges(BspBuilder &builder, BspLeaf &leaf)
void collatePolyHEdges(BspBuilder &builder, de::Polygon &geom)
{
HEdge *base = leaf.firstHEdge();
HEdge *base = geom.firstHEdge();
if(!base) return;

HEdge *hedge = base;
do
{
Expand All @@ -112,7 +114,6 @@ DENG2_PIMPL(GameMap)
}

// Calculate the length of the segment.
//DENG_ASSERT(&hedge->twin().vertex() != &hedge->vertex());
hedge->_length = Vector2d(hedge->twin().origin() - hedge->origin()).length();
if(hedge->_length == 0)
hedge->_length = 0.01f; // Hmm...
Expand Down Expand Up @@ -146,12 +147,21 @@ DENG2_PIMPL(GameMap)
leaf->setIndexInMap(bspLeafs.count());
bspLeafs.append(leaf);

collateBspLeafHEdges(builder, *leaf);
if(leaf->hasPoly())
{
de::Polygon &geom = leaf->poly();

collatePolyHEdges(builder, geom);

// The geometry of the leaf is now finalized; update dependent metadata.
leaf->poly().updateAABox();
leaf->poly().updateCenter();
leaf->updateWorldGridOffset();
// The geometry is now finalized.

/// @todo Polygon should encapsulate.
geom.updateAABox();
geom.updateCenter();

/// @todo leaf should observe.
leaf->updateWorldGridOffset();
}

return;
}
Expand Down

0 comments on commit 518b2a5

Please sign in to comment.