Skip to content

Commit

Permalink
Refactor: "Hardening" GameMap's BSP nodes and leafs is now unnecessary
Browse files Browse the repository at this point in the history
We can now simply collate the BspNode and BspLeaf pointers, from
the BspBuilder (taking ownership in the process).
  • Loading branch information
danij-deng committed Mar 17, 2013
1 parent 057d29c commit 0b69984
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 131 deletions.
12 changes: 6 additions & 6 deletions doomsday/client/include/map/gamemap.h
Expand Up @@ -107,12 +107,8 @@ class GameMap

/// BSP object LUTs:
de::MapElementList<HEdge> hedges;

uint numBspLeafs;
BspLeaf **bspLeafs;

uint numBspNodes;
BspNode **bspNodes;
de::MapElementList<BspNode> bspNodes;
de::MapElementList<BspLeaf> bspLeafs;

EntityDatabase *entityDatabase;

Expand Down Expand Up @@ -158,6 +154,10 @@ class GameMap

uint hedgeCount() const { return hedges.size(); }

uint bspNodeCount() const { return bspNodes.size(); }

uint bspLeafCount() const { return bspLeafs.size(); }

#ifdef __CLIENT__

/**
Expand Down
2 changes: 1 addition & 1 deletion doomsday/client/src/audio/s_environ.cpp
Expand Up @@ -149,7 +149,7 @@ static void findBspLeafsAffectingSector(GameMap *map, uint secIDX)
// LOG_DEBUG("sector %u: min[x:%f, y:%f] max[x:%f, y:%f]")
// << secIDX << aaBox.minX << aaBox.minY << aaBox.maxX << aaBox.maxY;

for(uint i = 0; i < map->numBspLeafs; ++i)
for(uint i = 0; i < map->bspLeafCount(); ++i)
{
BspLeaf *bspLeaf = GameMap_BspLeaf(map, i);

Expand Down
137 changes: 67 additions & 70 deletions doomsday/client/src/edit_bsp.cpp
Expand Up @@ -74,13 +74,13 @@ boolean BspBuilder_Build(BspBuilder_c* builder)
typedef struct {
GameMap *map;
BspBuilder *builder;
} hedgecollectorparams_t;
} HEdgeCollectParms;

static int hedgeCollector(BspTreeNode &tree, void *parameters)
{
if(tree.isLeaf())
{
hedgecollectorparams_t* p = static_cast<hedgecollectorparams_t*>(parameters);
HEdgeCollectParms* p = static_cast<HEdgeCollectParms*>(parameters);
BspLeaf *leaf = tree.userData()->castTo<BspLeaf>();
HEdge *base = leaf->firstHEdge();
HEdge *hedge = base;
Expand Down Expand Up @@ -118,42 +118,64 @@ static int hedgeCollector(BspTreeNode &tree, void *parameters)
static void collateHEdges(BspBuilder &builder, GameMap *map)
{
DENG2_ASSERT(map);
DENG_ASSERT(map->hedges.isEmpty());
DENG2_ASSERT(map->hedges.isEmpty());

if(!builder.numHEdges()) return; // Should never happen.
#ifdef DENG2_QT_4_7_OR_NEWER
map->hedges.reserve(builder.numHEdges());
#endif

hedgecollectorparams_t parm;
parm.builder = &builder;
parm.map = map;
builder.root()->traverseInOrder(hedgeCollector, &parm);
HEdgeCollectParms parms;
parms.builder = &builder;
parms.map = map;
builder.root()->traverseInOrder(hedgeCollector, &parms);
}

typedef struct {
BspBuilder *builder;
GameMap *dest;
uint leafCurIndex;
uint nodeCurIndex;
} populatebspobjectluts_params_t;
static void collateVertexes(BspBuilder &builder, GameMap *map,
uint *numEditableVertexes, Vertex const ***editableVertexes)
{
uint bspVertexCount = builder.numVertexes();

DENG2_ASSERT(map->vertexes.isEmpty());
#ifdef DENG2_QT_4_7_OR_NEWER
map->vertexes.reserve(*numEditableVertexes + bspVertexCount);
#endif

static int populateBspObjectLuts(BspTreeNode &tree, void *parameters)
uint n = 0;
for(; n < *numEditableVertexes; ++n)
{
Vertex *vtx = const_cast<Vertex *>((*editableVertexes)[n]);
map->vertexes.append(vtx);
}

for(uint i = 0; i < bspVertexCount; ++i, ++n)
{
Vertex &vtx = builder.vertex(i);

builder.take(&vtx);
map->vertexes.append(&vtx);
}
}

struct CollateBspElementsParms
{
populatebspobjectluts_params_t *p = static_cast<populatebspobjectluts_params_t*>(parameters);
DENG2_ASSERT(p);
BspBuilder *builder;
GameMap *map;
};

static void collateBspElements(BspTreeNode &tree, CollateBspElementsParms const &parms)
{
// We are only interested in BspNodes at this level.
if(tree.isLeaf()) return false; // Continue iteration.
if(tree.isLeaf()) return; // Continue iteration.

// Take ownership of this BspNode.
DENG2_ASSERT(tree.userData());
BspNode *node = tree.userData()->castTo<BspNode>();
p->builder->take(node);
parms.builder->take(node);

// Add this BspNode to the LUT.
node->_index = p->nodeCurIndex++;
p->dest->bspNodes[node->_index] = node;
node->_index = parms.map->bspNodes.count();
parms.map->bspNodes.append(node);

if(BspTreeNode *right = tree.right())
{
Expand All @@ -162,11 +184,11 @@ static int populateBspObjectLuts(BspTreeNode &tree, void *parameters)
// Take ownership of this BspLeaf.
DENG2_ASSERT(right->userData());
BspLeaf *leaf = right->userData()->castTo<BspLeaf>();
p->builder->take(leaf);
parms.builder->take(leaf);

// Add this BspLeaf to the LUT.
leaf->_index = p->leafCurIndex++;
p->dest->bspLeafs[leaf->_index] = leaf;
leaf->_index = parms.map->bspLeafs.count();
parms.map->bspLeafs.append(leaf);
}
}

Expand All @@ -177,30 +199,34 @@ static int populateBspObjectLuts(BspTreeNode &tree, void *parameters)
// Take ownership of this BspLeaf.
DENG2_ASSERT(left->userData());
BspLeaf *leaf = left->userData()->castTo<BspLeaf>();
p->builder->take(leaf);
parms.builder->take(leaf);

// Add this BspLeaf to the LUT.
leaf->_index = p->leafCurIndex++;
p->dest->bspLeafs[leaf->_index] = leaf;
leaf->_index = parms.map->bspLeafs.count();
parms.map->bspLeafs.append(leaf);
}
}
}

static int collateBspElementsWorker(BspTreeNode &tree, void *parameters)
{
collateBspElements(tree, *static_cast<CollateBspElementsParms *>(parameters));
return false; // Continue iteration.
}

static void hardenBSP(BspBuilder &builder, GameMap *dest)
static void collateBSP(BspBuilder &builder, GameMap *map)
{
dest->numBspNodes = builder.numNodes();
if(dest->numBspNodes != 0)
dest->bspNodes = static_cast<BspNode **>(Z_Malloc(dest->numBspNodes * sizeof(BspNode *), PU_MAPSTATIC, 0));
else
dest->bspNodes = 0;
DENG2_ASSERT(map);
DENG2_ASSERT(map->bspLeafs.isEmpty());
DENG2_ASSERT(map->bspNodes.isEmpty());

dest->numBspLeafs = builder.numLeafs();
dest->bspLeafs = static_cast<BspLeaf **>(Z_Calloc(dest->numBspLeafs * sizeof(BspLeaf *), PU_MAPSTATIC, 0));
#ifdef DENG2_QT_4_7_OR_NEWER
map->bspNodes.reserve(builder.numNodes());
map->bspLeafs.reserve(builder.numLeafs());
#endif

BspTreeNode *rootNode = builder.root();
dest->bsp = rootNode->userData();
map->bsp = rootNode->userData();

if(rootNode->isLeaf())
{
Expand All @@ -211,43 +237,15 @@ static void hardenBSP(BspBuilder &builder, GameMap *dest)

// Add this BspLeaf to the LUT.
leaf->_index = 0;
dest->bspLeafs[0] = leaf;
map->bspLeafs.append(leaf);

return;
}

populatebspobjectluts_params_t p;
p.builder = &builder;
p.dest = dest;
p.leafCurIndex = 0;
p.nodeCurIndex = 0;
rootNode->traversePostOrder(populateBspObjectLuts, &p);
}

static void collateVertexes(BspBuilder &builder, GameMap *map,
uint *numEditableVertexes, Vertex const ***editableVertexes)
{
uint bspVertexCount = builder.numVertexes();

DENG_ASSERT(map->vertexes.isEmpty());
#ifdef DENG2_QT_4_7_OR_NEWER
map->vertexes.reserve(*numEditableVertexes + bspVertexCount);
#endif

uint n = 0;
for(; n < *numEditableVertexes; ++n)
{
Vertex *vtx = const_cast<Vertex *>((*editableVertexes)[n]);
map->vertexes.append(vtx);
}

for(uint i = 0; i < bspVertexCount; ++i, ++n)
{
Vertex &vtx = builder.vertex(i);

builder.take(&vtx);
map->vertexes.append(&vtx);
}
CollateBspElementsParms parms;
parms.builder = &builder;
parms.map = map;
rootNode->traversePostOrder(collateBspElementsWorker, &parms);
}

void MPE_SaveBsp(BspBuilder_c *builder_c, GameMap *map, uint numEditableVertexes,
Expand All @@ -274,6 +272,5 @@ void MPE_SaveBsp(BspBuilder_c *builder_c, GameMap *map, uint numEditableVertexes

collateHEdges(builder, map);
collateVertexes(builder, map, &numEditableVertexes, &editableVertexes);

hardenBSP(builder, map);
collateBSP(builder, map);
}
12 changes: 6 additions & 6 deletions doomsday/client/src/edit_map.cpp
Expand Up @@ -474,9 +474,9 @@ static void hardenSectorBspLeafList(GameMap *map, uint secIDX)

#ifdef DENG2_QT_4_7_OR_NEWER
uint count = 0;
for(uint i = 0; i < map->numBspLeafs; ++i)
for(uint i = 0; i < map->bspLeafCount(); ++i)
{
BspLeaf &bspLeaf = *map->bspLeafs[i];
BspLeaf &bspLeaf = map->bspLeafs[i];
if(bspLeaf.sectorPtr() == sec)
++count;
}
Expand All @@ -485,9 +485,9 @@ static void hardenSectorBspLeafList(GameMap *map, uint secIDX)
sec->_bspLeafs.reserve(count);
#endif

for(uint i = 0; i < map->numBspLeafs; ++i)
for(uint i = 0; i < map->bspLeafCount(); ++i)
{
BspLeaf &bspLeaf = *map->bspLeafs[i];
BspLeaf &bspLeaf = map->bspLeafs[i];
if(bspLeaf.sectorPtr() == sec)
{
// Ownership of the BSP leaf is not given to the sector.
Expand Down Expand Up @@ -739,9 +739,9 @@ static void updateMapBounds(GameMap *map)
static void prepareBspLeafs(GameMap *map)
{
DENG_ASSERT(map);
for(uint i = 0; i < map->numBspLeafs; ++i)
for(uint i = 0; i < map->bspLeafCount(); ++i)
{
BspLeaf &bspLeaf = *map->bspLeafs[i];
BspLeaf &bspLeaf = map->bspLeafs[i];

bspLeaf.updateAABox();
bspLeaf.updateCenter();
Expand Down
22 changes: 9 additions & 13 deletions doomsday/client/src/map/dam_main.cpp
Expand Up @@ -280,9 +280,6 @@ boolean DAM_AttemptMapLoad(Uri const* _uri)

if(loadedOK)
{
vec2d_t min, max;
uint i;

// Do any initialization/error checking work we need to do.
// Must be called before we go any further.
P_InitUnusedMobjList();
Expand All @@ -300,10 +297,12 @@ boolean DAM_AttemptMapLoad(Uri const* _uri)

Rend_DecorInit();

// Init blockmap for searching BSP leafs.
vec2d_t min, max;
GameMap_Bounds(map, min, max);

// Init blockmap for searching BSP leafs.
GameMap_InitBspLeafBlockmap(map, min, max);
for(i = 0; i < map->numBspLeafs; ++i)
for(uint i = 0; i < map->bspLeafCount(); ++i)
{
GameMap_LinkBspLeaf(map, GameMap_BspLeaf(map, i));
}
Expand All @@ -312,21 +311,21 @@ boolean DAM_AttemptMapLoad(Uri const* _uri)

// Generate the unique map id.
lumpnum_t markerLumpNum = App_FileSystem().lumpNumForName(Str_Text(Uri_Path(map->uri)));
de::File1& markerLump = App_FileSystem().nameIndex().lump(markerLumpNum);
de::File1 &markerLump = App_FileSystem().nameIndex().lump(markerLumpNum);

de::String uniqueId = DAM_ComposeUniqueId(markerLump);
QByteArray uniqueIdUtf8 = uniqueId.toUtf8();
qstrncpy(map->uniqueId, uniqueIdUtf8.constData(), sizeof(map->uniqueId));

// See what mapinfo says about this map.
ded_mapinfo_t* mapInfo = Def_GetMapInfo(map->uri);
ded_mapinfo_t *mapInfo = Def_GetMapInfo(map->uri);
if(!mapInfo)
{
de::Uri mapUri = de::Uri("*", RC_NULL);
mapInfo = Def_GetMapInfo(reinterpret_cast<uri_s*>(&mapUri));
de::Uri mapUri("*", RC_NULL);
mapInfo = Def_GetMapInfo(reinterpret_cast<uri_s *>(&mapUri));
}

ded_sky_t* skyDef = 0;
ded_sky_t *skyDef = 0;
if(mapInfo)
{
skyDef = Def_GetSky(mapInfo->skyID);
Expand Down Expand Up @@ -361,10 +360,7 @@ boolean DAM_AttemptMapLoad(Uri const* _uri)
Rend_RadioInitForMap();
#endif

{ uint startTime = Timer_RealMilliseconds();
GameMap_InitSkyFix(map);
VERBOSE2( Con_Message("Initial sky fix done in %.2f seconds.", (Timer_RealMilliseconds() - startTime) / 1000.0f) );
}
}
}

Expand Down

0 comments on commit 0b69984

Please sign in to comment.