Skip to content

Commit

Permalink
Optimize|Bsp Builder: Reduced working memory requirement
Browse files Browse the repository at this point in the history
Each recursion of the partitioning algorithm allocates a duplicate
of the previous iteration's SuperBlockmap, which, was previously
retained until all further subdivisions had completed.

The blockmap for each subdivision is now cleared once the half-edges
have been either partitioned or collected to build a new BSP leaf
(the underlying kd-tree is reduced to a single root node).
  • Loading branch information
danij-deng committed Sep 1, 2012
1 parent 13e1936 commit 080eac9
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 23 deletions.
2 changes: 2 additions & 0 deletions doomsday/engine/portable/include/kdtree.h
Expand Up @@ -58,6 +58,8 @@ struct kdtreenode_s* KdTree_Root(KdTree* kdTree);
int KdTree_PostTraverse2(KdTree* kdTree, int(*callback)(KdTreeNode*, void*), void* parameters);
int KdTree_PostTraverse(KdTree* kdTree, int(*callback)(KdTreeNode*, void*)/*, parameters=NULL*/);

void KdTreeNode_Delete(KdTreeNode* kdTreeNode);

KdTree* KdTreeNode_KdTree(KdTreeNode* kdTreeNode);

const AABox* KdTreeNode_Bounds(KdTreeNode* kdTreeNode);
Expand Down
3 changes: 3 additions & 0 deletions doomsday/engine/portable/include/map/bsp/superblockmap.h
Expand Up @@ -115,6 +115,9 @@ class SuperBlock
Q_ASSERT(childId == RIGHT || childId == LEFT);
}

public:
SuperBlock& clear();

/**
* Retrieve the SuperBlockmap which owns this block.
* @return The owning SuperBlockmap instance.
Expand Down
15 changes: 12 additions & 3 deletions doomsday/engine/portable/src/kdtree.c
Expand Up @@ -54,8 +54,6 @@ struct kdtreenode_s {
static KdTreeNode* KdTreeNode_New(KdTree* kdTree, const AABox* bounds);
static KdTreeNode* KdTreeNode_NewWithUserData(KdTree* kdTree, const AABox* bounds, void* userData);

static void KdTreeNode_Delete(KdTreeNode* kdTreeNode);

static int KdTreeNode_PostTraverse2(KdTreeNode* kdn, int(*callback)(KdTreeNode*, void*), void* parameters);
static int KdTreeNode_PostTraverse(KdTreeNode* kdn, int(*callback)(KdTreeNode*, void*)/*, parameters=NULL*/);

Expand Down Expand Up @@ -116,9 +114,20 @@ static KdTreeNode* KdTreeNode_New(KdTree* kdTree, const AABox* bounds)
return KdTreeNode_NewWithUserData(kdTree, bounds, NULL/*no user data*/);
}

static void KdTreeNode_Delete(KdTreeNode* kdn)
void KdTreeNode_Delete(KdTreeNode* kdn)
{
assert(kdn);
if(kdn->parent)
{
if(kdn->parent->subs[0] == kdn)
{
kdn->parent->subs[0] = 0;
}
else if(kdn->parent->subs[1] == kdn)
{
kdn->parent->subs[1] = 0;
}
}
free(kdn);
}

Expand Down
3 changes: 3 additions & 0 deletions doomsday/engine/portable/src/map/bsp/partitioner.cpp
Expand Up @@ -1330,6 +1330,7 @@ struct Partitioner::Instance
// Divide the half-edges into two subsets according to their spacial
// relationship with the half-plane (splitting any which intersect).
partitionHEdges(partList, rightHEdges, leftHEdges);
partList.clear();
addMiniHEdges(rightHEdges, leftHEdges);
clearPartitionIntercepts();

Expand All @@ -1355,6 +1356,8 @@ struct Partitioner::Instance
{
// No partition required/possible - already convex (or degenerate).
BspLeaf* leaf = buildBspLeaf(collectHEdges(partList));
partList.clear();

// Not a leaf? (collapse upward).
if(!leaf) return 0;

Expand Down
41 changes: 21 additions & 20 deletions doomsday/engine/portable/src/map/bsp/superblockmap.cpp
Expand Up @@ -50,7 +50,7 @@ struct SuperBlock::Instance

~Instance()
{
KdTreeNode_SetUserData(tree, NULL);
KdTreeNode_Delete(tree);
}

inline void linkHEdge(HEdge& hedge)
Expand Down Expand Up @@ -84,9 +84,28 @@ SuperBlock::SuperBlock(SuperBlock& parent, ChildId childId, bool splitVertical)

SuperBlock::~SuperBlock()
{
clear();
delete d;
}

SuperBlock& SuperBlock::clear()
{
if(d->tree)
{
// Recursively handle sub-blocks.
KdTreeNode* child;
for(uint num = 0; num < 2; ++num)
{
child = KdTreeNode_Child(d->tree, num);
if(!child) continue;

SuperBlock* blockPtr = static_cast<SuperBlock*>(KdTreeNode_UserData(child));
if(blockPtr) delete blockPtr;
}
}
return *this;
}

SuperBlockmap& SuperBlock::blockmap() const
{
return d->bmap;
Expand Down Expand Up @@ -295,24 +314,6 @@ struct SuperBlockmap::Instance
{
KdTree_Delete(kdTree);
}

void clearBlockWorker(SuperBlock& block)
{
if(block.d->tree)
{
// Recursively handle sub-blocks.
KdTreeNode* child;
for(uint num = 0; num < 2; ++num)
{
child = KdTreeNode_Child(block.d->tree, num);
if(!child) continue;

SuperBlock* blockPtr = static_cast<SuperBlock*>(KdTreeNode_UserData(child));
if(blockPtr) clearBlockWorker(*blockPtr);
}
}
delete &block;
}
};

SuperBlockmap::SuperBlockmap(const AABox& bounds)
Expand All @@ -333,7 +334,7 @@ SuperBlock& SuperBlockmap::root()

void SuperBlockmap::clear()
{
d->clearBlockWorker(root());
root().clear();
}

static void findHEdgeBoundsWorker(SuperBlock& block, AABoxd& bounds, bool* initialized)
Expand Down

0 comments on commit 080eac9

Please sign in to comment.