Skip to content

Commit

Permalink
BSP Builder|Refactor: Renamed KdTree as KdTreeNode and implemented Kd…
Browse files Browse the repository at this point in the history
…Tree the container

Also restricted KdTreeNode (de)constructor access to KdTree.
  • Loading branch information
danij-deng committed Mar 20, 2012
1 parent d34c221 commit 1ca124d
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 101 deletions.
22 changes: 11 additions & 11 deletions doomsday/engine/portable/include/bsp_superblock.h
Expand Up @@ -47,35 +47,38 @@ typedef struct superblockmap_s SuperBlockmap;
typedef struct superblock_s SuperBlock;

/**
* Constructs a new superblockmap. The superblockmap must be destroyed with
* Constructs a new superBlockmap. The superBlockmap must be destroyed with
* SuperBlockmap_Delete() when no longer needed.
*/
SuperBlockmap* SuperBlockmap_New(const AABox* bounds);

/**
* Destroys the superblockmap.
* Destroys the superBlockmap.
*
* @param superblockmap SuperBlockmap instance.
* @param superBlockmap SuperBlockmap instance.
*/
void SuperBlockmap_Delete(SuperBlockmap* superblockmap);
void SuperBlockmap_Delete(SuperBlockmap* superBlockmap);

/**
* Retrieve the root SuperBlock in this SuperBlockmap.
*
* @param superblockmap SuperBlockmap instance.
* @param superBlockmap SuperBlockmap instance.
* @return Root SuperBlock instance.
*/
SuperBlock* SuperBlockmap_Root(SuperBlockmap* superblockmap);
SuperBlock* SuperBlockmap_Root(SuperBlockmap* superBlockmap);

/**
* Find the axis-aligned bounding box defined by the vertices of all
* HEdges within this superblock. If no HEdges are linked then @a bounds
* will be set to the "cleared" state (i.e., min[x,y] > max[x,y]).
*
* @param superblockmap SuperBlock instance.
* @param superBlockmap SuperBlock instance.
* @param bounds Determined bounds are written here.
*/
void SuperBlockmap_FindHEdgeBounds(SuperBlockmap* superblockmap, AABoxf* bounds);
void SuperBlockmap_FindHEdgeBounds(SuperBlockmap* superBlockmap, AABoxf* bounds);

int SuperBlockmap_PostTraverse2(SuperBlockmap* superBlockmap, int(*callback)(SuperBlock*, void*), void* parameters);
int SuperBlockmap_PostTraverse(SuperBlockmap* superBlockmap, int(*callback)(SuperBlock*, void*)/*, parameters = NULL*/);

/**
* Retrieve the SuperBlockmap which owns this block.
Expand Down Expand Up @@ -156,7 +159,4 @@ SuperBlock* SuperBlock_Child(SuperBlock* superblock, int left);
int SuperBlock_Traverse2(SuperBlock* superblock, int (*callback)(SuperBlock*, void*), void* parameters);
int SuperBlock_Traverse(SuperBlock* superblock, int (*callback)(SuperBlock*, void*)/*, parameters=NULL*/);

int SuperBlock_PostTraverse2(SuperBlock* sb, int(*callback)(SuperBlock*, void*), void* parameters);
int SuperBlock_PostTraverse(SuperBlock* sb, int(*callback)(SuperBlock*, void*)/*, parameters = NULL*/);

#endif /// LIBDENG_MAP_BSP_SUPERBLOCK
36 changes: 26 additions & 10 deletions doomsday/engine/portable/include/kdtree.h
Expand Up @@ -31,27 +31,43 @@
#include "de_platform.h"

struct kdtree_s;
struct kdtreenode_s;

typedef struct kdtree_s KdTree;
typedef struct kdtreenode_s KdTreeNode;

/**
* Constructs a new KdTree. The kd-tree must be destroyed with KdTree_Delete()
* when no longer needed.
*/
KdTree* KdTree_New(const AABox* bounds);
KdTree* KdTree_NewWithUserData(const AABox* bounds, void* userData);

/**
* Destroys the KdTree.
*
* @param kdTree KdTree instance.
*/
void KdTree_Delete(KdTree* kdTree);

const AABox* KdTree_Bounds(KdTree* kdTree);
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*/);

KdTree* KdTreeNode_KdTree(KdTreeNode* kdTreeNode);

const AABox* KdTreeNode_Bounds(KdTreeNode* kdTreeNode);

void* KdTree_UserData(KdTree* kdTree);
KdTree* KdTree_SetUserData(KdTree* kdTree, void* userData);
void* KdTreeNode_UserData(KdTreeNode* kdTreeNode);
KdTreeNode* KdTreeNode_SetUserData(KdTreeNode* kdTreeNode, void* userData);

KdTree* KdTree_Child(KdTree* kdTree, int left);
KdTreeNode* KdTreeNode_Parent(KdTreeNode* kdTreeNode);

KdTree* KdTree_AddChild(KdTree* kdTree, const AABox* bounds, int left, void* userData);
KdTreeNode* KdTreeNode_Child(KdTreeNode* kdTreeNode, int left);

int KdTree_Traverse2(KdTree* kdTree, int (*callback)(KdTree*, void*), void* parameters);
int KdTree_Traverse(KdTree* kdTree, int (*callback)(KdTree*, void*), void* parameters);
KdTreeNode* KdTreeNode_AddChild(KdTreeNode* kdTreeNode, const AABox* bounds, int left, void* userData);

int KdTree_PostTraverse2(KdTree* kdTree, int(*callback)(KdTree*, void*), void* parameters);
int KdTree_PostTraverse(KdTree* kdTree, int(*callback)(KdTree*, void*)/*, parameters=NULL*/);
int KdTreeNode_Traverse2(KdTreeNode* kdTreeNode, int (*callback)(KdTreeNode*, void*), void* parameters);
int KdTreeNode_Traverse(KdTreeNode* kdTreeNode, int (*callback)(KdTreeNode*, void*), void* parameters);

#endif /// LIBDENG_KDTREE
68 changes: 35 additions & 33 deletions doomsday/engine/portable/src/bsp_superblock.c
Expand Up @@ -41,7 +41,7 @@ struct superblock_s {
struct superblockmap_s* blockmap;

/// KdTree node in the owning SuperBlockmap.
KdTree* tree;
KdTreeNode* tree;

/// Number of real half-edges and minihedges contained by this block
/// (including all sub-blocks below it).
Expand Down Expand Up @@ -70,28 +70,41 @@ static void SuperBlock_Delete(SuperBlock* superblock);
* Division of a block always occurs horizontally, e.g. 512x512 -> 256x512 -> 256x256.
*/
struct superblockmap_s {
SuperBlock* root;
KdTree* kdTree;
};

SuperBlockmap* SuperBlockmap_New(const AABox* bounds)
{
SuperBlockmap* bmap = malloc(sizeof *bmap);
SuperBlock* block;
if(!bmap) Con_Error("SuperBlockmap_New: Failed on allocation of %lu bytes for new SuperBlockmap.", (unsigned long) sizeof *bmap);
bmap->root = SuperBlock_New(bmap, bounds);
bmap->kdTree = KdTree_New(bounds);

block = SuperBlock_New(bmap, bounds);
block->tree = KdTreeNode_SetUserData(KdTree_Root(bmap->kdTree), block);

return bmap;
}

static int deleteSuperBlock(SuperBlock* block, void* parameters)
{
KdTreeNode_SetUserData(block->tree, NULL);
SuperBlock_Delete(block);
return false; // Continue iteration.
}

void SuperBlockmap_Delete(SuperBlockmap* bmap)
{
assert(bmap);
SuperBlock_Delete(bmap->root);
SuperBlockmap_PostTraverse(bmap, deleteSuperBlock);
KdTree_Delete(bmap->kdTree);
free(bmap);
}

SuperBlock* SuperBlockmap_Root(SuperBlockmap* bmap)
{
assert(bmap);
return bmap->root;
return KdTreeNode_UserData(KdTree_Root(bmap->kdTree));
}

static __inline boolean isLeaf(SuperBlockmap* blockmap, SuperBlock* sb)
Expand All @@ -115,27 +128,16 @@ SuperBlock* SuperBlock_New(SuperBlockmap* blockmap, const AABox* bounds)
SuperBlock* sb = malloc(sizeof *sb);
if(!sb) Con_Error("SuperBlock_New: Failed on allocation of %lu bytes for new SuperBlock.", (unsigned long) sizeof *sb);
sb->blockmap = blockmap;
sb->tree = KdTree_NewWithUserData(bounds, sb);
sb->realNum = 0;
sb->miniNum = 0;
sb->hEdges = NULL;
return sb;
}

static int deleteSuperBlock(SuperBlock* sb, void* parameters)
{
M_Free(sb);
return false; // Continue iteration.
}

void SuperBlock_Delete(SuperBlock* sb)
{
KdTree* tree;
assert(sb);

tree = sb->tree;
SuperBlock_PostTraverse(sb, deleteSuperBlock);
KdTree_Delete(tree);
free(sb);
}

SuperBlockmap* SuperBlock_Blockmap(SuperBlock* sb)
Expand All @@ -147,7 +149,7 @@ SuperBlockmap* SuperBlock_Blockmap(SuperBlock* sb)
const AABox* SuperBlock_Bounds(SuperBlock* sb)
{
assert(sb);
return KdTree_Bounds(sb->tree);
return KdTreeNode_Bounds(sb->tree);
}

uint SuperBlock_HEdgeCount(SuperBlock* sb, boolean addReal, boolean addMini)
Expand Down Expand Up @@ -217,7 +219,7 @@ void SuperBlock_HEdgePush(SuperBlock* sb, bsp_hedge_t* hEdge)

// The hedge lies in one half of this block. Create the sub-block
// if it doesn't already exist, and loop back to add the hedge.
if(!KdTree_Child(sb->tree, half))
if(!KdTreeNode_Child(sb->tree, half))
{
SuperBlock* child;
AABox sub;
Expand All @@ -241,10 +243,10 @@ void SuperBlock_HEdgePush(SuperBlock* sb, bsp_hedge_t* hEdge)
}

child = SuperBlock_New(SuperBlock_Blockmap(sb), &sub);
child->tree = KdTree_AddChild(sb->tree, &sub, half, child);
child->tree = KdTreeNode_AddChild(sb->tree, &sub, half, child);
}

sb = KdTree_UserData(KdTree_Child(sb->tree, half));
sb = (SuperBlock*)KdTreeNode_UserData(KdTreeNode_Child(sb->tree, half));
}
}

Expand Down Expand Up @@ -292,22 +294,22 @@ int SuperBlock_IterateHEdges(SuperBlock* sp, int (*callback)(bsp_hedge_t*, void*

SuperBlock* SuperBlock_Child(SuperBlock* sb, int left)
{
KdTree* child;
KdTreeNode* child;
assert(sb);
child = KdTree_Child(sb->tree, left);
child = KdTreeNode_Child(sb->tree, left);
if(!child) return NULL;
return (SuperBlock*)KdTree_UserData(child);
return (SuperBlock*)KdTreeNode_UserData(child);
}

typedef struct {
int (*callback)(SuperBlock*, void*);
void* parameters;
} treetraverserparams_t;

static int SuperBlock_TreeTraverser(KdTree* kd, void* parameters)
static int SuperBlock_TreeTraverser(KdTreeNode* kd, void* parameters)
{
treetraverserparams_t* p = (treetraverserparams_t*)parameters;
return p->callback(KdTree_UserData(kd), p->parameters);
return p->callback(KdTreeNode_UserData(kd), p->parameters);
}

int SuperBlock_Traverse2(SuperBlock* sb, int (*callback)(SuperBlock*, void*),
Expand All @@ -319,29 +321,29 @@ int SuperBlock_Traverse2(SuperBlock* sb, int (*callback)(SuperBlock*, void*),

parm.callback = callback;
parm.parameters = parameters;
return KdTree_Traverse2(sb->tree, SuperBlock_TreeTraverser, (void*)&parm);
return KdTreeNode_Traverse2(sb->tree, SuperBlock_TreeTraverser, (void*)&parm);
}

int SuperBlock_Traverse(SuperBlock* sb, int (*callback)(SuperBlock*, void*))
{
return SuperBlock_Traverse2(sb, callback, NULL/*no parameters*/);
}

int SuperBlock_PostTraverse2(SuperBlock* sb, int(*callback)(SuperBlock*, void*),
int SuperBlockmap_PostTraverse2(SuperBlockmap* sbmap, int(*callback)(SuperBlock*, void*),
void* parameters)
{
treetraverserparams_t parm;
assert(sb);
assert(sbmap);
if(!callback) return false; // Continue iteration.

parm.callback = callback;
parm.parameters = parameters;
return KdTree_PostTraverse2(sb->tree, SuperBlock_TreeTraverser, (void*)&parm);
return KdTree_PostTraverse2(sbmap->kdTree, SuperBlock_TreeTraverser, (void*)&parm);
}

int SuperBlock_PostTraverse(SuperBlock* sb, int(*callback)(SuperBlock*, void*))
int SuperBlockmap_PostTraverse(SuperBlockmap* sbmap, int(*callback)(SuperBlock*, void*))
{
return SuperBlock_PostTraverse2(sb, callback, NULL/*no parameters*/);
return SuperBlockmap_PostTraverse2(sbmap, callback, NULL/*no parameters*/);
}

static void initAABoxFromHEdgeVertexes(AABoxf* aaBox, const bsp_hedge_t* hEdge)
Expand Down Expand Up @@ -389,7 +391,7 @@ void SuperBlockmap_FindHEdgeBounds(SuperBlockmap* sbmap, AABoxf* aaBox)
assert(sbmap && aaBox);

parm.initialized = false;
SuperBlock_Traverse2(sbmap->root, findHEdgeListBoundsWorker, (void*)&parm);
SuperBlock_Traverse2(SuperBlockmap_Root(sbmap), findHEdgeListBoundsWorker, (void*)&parm);
if(parm.initialized)
{
V2_CopyBox(aaBox->arvec2, parm.bounds.arvec2);
Expand Down

0 comments on commit 1ca124d

Please sign in to comment.