Skip to content

Commit

Permalink
World|Map: Use a ConvexSubspace Blockmap (was BspLeaf)
Browse files Browse the repository at this point in the history
  • Loading branch information
danij-deng committed Oct 22, 2014
1 parent 40c8e16 commit f501d7e
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 76 deletions.
9 changes: 5 additions & 4 deletions doomsday/client/include/world/map.h
Expand Up @@ -50,6 +50,7 @@
class MapDef;
class BspLeaf;
class BspNode;
class ConvexSubspace;
class Plane;
class Sector;
class SectorCluster;
Expand Down Expand Up @@ -337,9 +338,9 @@ class Map
Blockmap const &polyobjBlockmap() const;

/**
* Provides access to the BSP leaf blockmap.
* Provides access to the convex subspace blockmap.
*/
Blockmap const &bspLeafBlockmap() const;
Blockmap const &subspaceBlockmap() const;

/**
* Returns @c true iff a BSP tree is available for the map.
Expand Down Expand Up @@ -475,8 +476,8 @@ class Map
return linePathIterator(from, to, LIF_ALL, callback, context);
}

int bspLeafBoxIterator(AABoxd const &box,
int (*callback) (BspLeaf *bspLeaf, void *context), void *context = 0) const;
int subspaceBoxIterator(AABoxd const &box,
int (*callback) (ConvexSubspace *subspace, void *context), void *context = 0) const;

/**
* @note validCount should be incremented before calling this to begin a
Expand Down
29 changes: 13 additions & 16 deletions doomsday/client/src/render/blockmapvisual.cpp
Expand Up @@ -41,7 +41,7 @@
#include "world/map.h"
#include "world/p_object.h"
#include "world/p_players.h"
#include "BspLeaf"
#include "ConvexSubspace"

#include "render/blockmapvisual.h"

Expand Down Expand Up @@ -88,15 +88,12 @@ static int drawLineWorker(void *linePtr, void * /*context*/)
return false; // Continue iteration.
}

static void drawBspLeaf(BspLeaf const &bspLeaf)
static void drawSubspace(ConvexSubspace const &subspace)
{
if(!bspLeaf.hasSubspace())
return;

float const scale = de::max(bmapDebugSize, 1.f);
float const width = (DENG_GAMEVIEW_WIDTH / 16) / scale;

Face const &poly = bspLeaf.poly();
Face const &poly = subspace.poly();
HEdge *base = poly.hedge();
HEdge *hedge = base;
do
Expand Down Expand Up @@ -152,13 +149,13 @@ static void drawBspLeaf(BspLeaf const &bspLeaf)
} while((hedge = &hedge->next()) != base);
}

static int drawBspLeafWorker(void *bspLeafPtr, void * /*context*/)
static int drawSubspaceWorker(void *subspacePtr, void * /*context*/)
{
BspLeaf &bspLeaf = *static_cast<BspLeaf *>(bspLeafPtr);
if(bspLeaf.hasSubspace() && bspLeaf.subspace().validCount() != validCount)
ConvexSubspace &subspace = *static_cast<ConvexSubspace *>(subspacePtr);
if(subspace.validCount() != validCount)
{
bspLeaf.subspace().setValidCount(validCount);
drawBspLeaf(bspLeaf);
subspace.setValidCount(validCount);
drawSubspace(subspace);
}
return false; // Continue iteration.
}
Expand Down Expand Up @@ -198,9 +195,9 @@ static int drawCellMobjs(Blockmap const &bmap, BlockmapCell const &cell, void *c
return false; // Continue iteration.
}

static int drawCellBspLeafs(Blockmap const &bmap, BlockmapCell const &cell, void *context)
static int drawCellSubspaces(Blockmap const &bmap, BlockmapCell const &cell, void *context)
{
bmap.iterate(cell, (int (*)(void*,void*)) drawBspLeafWorker, context);
bmap.iterate(cell, (int (*)(void*,void*)) drawSubspaceWorker, context);
return false; // Continue iteration.
}

Expand Down Expand Up @@ -539,9 +536,9 @@ void Rend_BlockmapDebug()
break;

case 3: // BSP leafs.
blockmap = &map.bspLeafBlockmap();
cellDrawer = drawCellBspLeafs;
objectTypeName = "BSP Leafs";
blockmap = &map.subspaceBlockmap();
cellDrawer = drawCellSubspaces;
objectTypeName = "Subspaces";
break;

case 4: // Polyobjs.
Expand Down
5 changes: 2 additions & 3 deletions doomsday/client/src/render/r_fakeradio.cpp
Expand Up @@ -194,9 +194,8 @@ void Rend_RadioUpdateVertexShadowOffsets(Vertex &vtx)
} while(own != base);
}

static int linkShadowLineToBspLeafWorker(BspLeaf *bspLeaf, void *context)
static int linkShadowLineToSubspaceWorker(ConvexSubspace *subspace, void *context)
{
ConvexSubspace *subspace = bspLeaf->subspacePtr();
LineSide &side = *static_cast<LineSide *>(context);
if(side.sectorPtr() == &subspace->cluster().sector())
{
Expand Down Expand Up @@ -259,7 +258,7 @@ void Rend_RadioInitForMap(Map &map)

// Link the shadowing line to all the BspLeafs whose axis-aligned
// bounding box intersects 'bounds'.
map.bspLeafBoxIterator(bounds, linkShadowLineToBspLeafWorker, &side);
map.subspaceBoxIterator(bounds, linkShadowLineToSubspaceWorker, &side);
}
}

Expand Down
20 changes: 8 additions & 12 deletions doomsday/client/src/render/rend_main.cpp
Expand Up @@ -4952,20 +4952,16 @@ static void findMinMaxPlaneHeightsAtVertex(HEdge *base, int edge,
}
}

static int drawBspLeafVertexWorker(BspLeaf *bspLeaf, void *context)
static int drawSubspaceVertexWorker(ConvexSubspace *subspace, void *context)
{
drawVertexVisual_params_t &parms = *static_cast<drawVertexVisual_params_t *>(context);

if(!bspLeaf->hasSubspace())
return false; // Continue iteration.

ConvexSubspace &subspace = bspLeaf->subspace();
SectorCluster &cluster = subspace.cluster();
SectorCluster &cluster = subspace->cluster();

ddouble min = cluster. visFloor().heightSmoothed();
ddouble max = cluster.visCeiling().heightSmoothed();

HEdge *base = subspace.poly().hedge();
HEdge *base = subspace->poly().hedge();
HEdge *hedge = base;
do
{
Expand All @@ -4977,14 +4973,14 @@ static int drawBspLeafVertexWorker(BspLeaf *bspLeaf, void *context)

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

foreach(Mesh *mesh, subspace.extraMeshes())
foreach(Mesh *mesh, subspace->extraMeshes())
foreach(HEdge *hedge, mesh->hedges())
{
drawVertexVisual(hedge->vertex(), min, max, parms);
drawVertexVisual(hedge->twin().vertex(), min, max, parms);
}

foreach(Polyobj *polyobj, subspace.polyobjs())
foreach(Polyobj *polyobj, subspace->polyobjs())
foreach(Line *line, polyobj->lines())
{
drawVertexVisual(line->from(), min, max, parms);
Expand Down Expand Up @@ -5024,7 +5020,7 @@ static void drawVertexes(Map &map)

parms.drawBar = true;
parms.drawLabel = parms.drawOrigin = false;
map.bspLeafBoxIterator(box, drawBspLeafVertexWorker, &parms);
map.subspaceBoxIterator(box, drawSubspaceVertexWorker, &parms);

glEnable(GL_DEPTH_TEST);
}
Expand All @@ -5040,7 +5036,7 @@ static void drawVertexes(Map &map)
parms.drawnVerts->fill(false); // Process all again.
parms.drawOrigin = true;
parms.drawBar = parms.drawLabel = false;
map.bspLeafBoxIterator(box, drawBspLeafVertexWorker, &parms);
map.subspaceBoxIterator(box, drawSubspaceVertexWorker, &parms);

glEnable(GL_DEPTH_TEST);

Expand All @@ -5049,7 +5045,7 @@ static void drawVertexes(Map &map)
parms.drawnVerts->fill(false); // Process all again.
parms.drawLabel = true;
parms.drawBar = parms.drawOrigin = false;
map.bspLeafBoxIterator(box, drawBspLeafVertexWorker, &parms);
map.subspaceBoxIterator(box, drawSubspaceVertexWorker, &parms);
}

// Restore previous state.
Expand Down
19 changes: 18 additions & 1 deletion doomsday/client/src/world/api_map.cpp
Expand Up @@ -1615,12 +1615,29 @@ DENG_EXTERN_C int Line_BoxIterator(AABoxd const *box, int flags,
return App_WorldSystem().map().lineBoxIterator(*box, flags, callback, context);
}

struct subspaceblockmapbspleaftraverser_params_t
{
int (*callback) (BspLeaf *, void *);
void *context;
};

static int subspaceBlockmapBspLeafTraverser(ConvexSubspace *subspace, void *context)
{
subspaceblockmapbspleaftraverser_params_t &p = *static_cast<subspaceblockmapbspleaftraverser_params_t *>(context);
return p.callback(&subspace->bspLeaf(), p.context);
}

/// @note Used only for drawing the games' automap.
#undef BspLeaf_BoxIterator
DENG_EXTERN_C int BspLeaf_BoxIterator(AABoxd const *box,
int (*callback) (BspLeaf *, void *), void *context)
{
if(!box || !App_WorldSystem().hasMap()) return false; // Continue iteration.
return App_WorldSystem().map().bspLeafBoxIterator(*box, callback, context);

subspaceblockmapbspleaftraverser_params_t parm; de::zap(parm);
parm.callback = callback;
parm.context = context;
return App_WorldSystem().map().subspaceBoxIterator(*box, subspaceBlockmapBspLeafTraverser, &parm);
}

#undef P_PathTraverse2
Expand Down
70 changes: 34 additions & 36 deletions doomsday/client/src/world/map.cpp
Expand Up @@ -141,7 +141,7 @@ DENG2_PIMPL(Map)
QScopedPointer<Blockmap> mobjBlockmap;
QScopedPointer<Blockmap> polyobjBlockmap;
QScopedPointer<LineBlockmap> lineBlockmap;
QScopedPointer<Blockmap> bspLeafBlockmap;
QScopedPointer<Blockmap> subspaceBlockmap;

#ifdef __CLIENT__
struct ContactBlockmap : public Blockmap
Expand Down Expand Up @@ -989,28 +989,27 @@ DENG2_PIMPL(Map)
}

/**
* Construct an initial (empty) BSP leaf blockmap.
* Construct an initial (empty) convex subspace blockmap.
*
* @pre Coordinate space bounds have already been determined.
*/
void initBspLeafBlockmap(ddouble margin = 8)
void initSubspaceBlockmap(ddouble margin = 8)
{
// Setup the blockmap area to enclose the whole map, plus a margin
// (margin is needed for a map that fits entirely inside one blockmap cell).
bspLeafBlockmap.reset(
subspaceBlockmap.reset(
new Blockmap(AABoxd(bounds.minX - margin, bounds.minY - margin,
bounds.maxX + margin, bounds.maxY + margin)));

LOG_MAP_VERBOSE("BSP leaf blockmap dimensions:")
<< bspLeafBlockmap->dimensions().asText();
LOG_MAP_VERBOSE("Convex subspace blockmap dimensions:")
<< subspaceBlockmap->dimensions().asText();

// Populate the blockmap.
foreach(BspLeaf *bspLeaf, bspLeafs)
{
// BspLeafs without a sector cluster don't get in.
if(bspLeaf->hasCluster())
if(ConvexSubspace *subspace = bspLeaf->subspacePtr())
{
bspLeafBlockmap->link(bspLeaf->poly().aaBox(), bspLeaf);
subspaceBlockmap->link(subspace->poly().aaBox(), subspace);
}
}
}
Expand Down Expand Up @@ -2265,14 +2264,14 @@ LineBlockmap const &Map::lineBlockmap() const
throw MissingBlockmapError("Map::lineBlockmap", "Line blockmap is not initialized");
}

Blockmap const &Map::bspLeafBlockmap() const
Blockmap const &Map::subspaceBlockmap() const
{
if(!d->bspLeafBlockmap.isNull())
if(!d->subspaceBlockmap.isNull())
{
return *d->bspLeafBlockmap;
return *d->subspaceBlockmap;
}
/// @throw MissingBlockmapError The BSP leaf blockmap is not yet initialized.
throw MissingBlockmapError("Map::bspLeafBlockmap", "BSP leaf blockmap is not initialized");
/// @throw MissingBlockmapError The subspace blockmap is not yet initialized.
throw MissingBlockmapError("Map::subspaceBlockmap", "Convex subspace blockmap is not initialized");
}

struct blockmapcellmobjsiterator_params_t
Expand Down Expand Up @@ -2357,27 +2356,26 @@ static int blockmapCellLinesIterator(void *mapElement, void *context)
return false; // Continue iteration.
}

struct blockmapcellbspleafsiterator_params_t
struct blockmapcellsubspacesiterator_params_t
{
AABoxd const *box;
int localValidCount;
int (*callback) (BspLeaf *, void *);
int (*callback) (ConvexSubspace *, void *);
void *context;
};

static int blockmapCellBspLeafsIterator(void *object, void *context)
static int blockmapCellSubspacesIterator(void *object, void *context)
{
BspLeaf *bspLeaf = static_cast<BspLeaf *>(object);
DENG2_ASSERT(bspLeaf->hasSubspace()); // sanity check
blockmapcellbspleafsiterator_params_t &parm = *static_cast<blockmapcellbspleafsiterator_params_t *>(context);
ConvexSubspace *subspace = static_cast<ConvexSubspace *>(object);
blockmapcellsubspacesiterator_params_t &parm = *static_cast<blockmapcellsubspacesiterator_params_t *>(context);

if(bspLeaf->subspace().validCount() != parm.localValidCount)
if(subspace->validCount() != parm.localValidCount)
{
// This BspLeaf has now been processed for the current iteration.
bspLeaf->subspace().setValidCount(parm.localValidCount);
// This subspace has now been processed for the current iteration.
subspace->setValidCount(parm.localValidCount);

// Check the bounds.
AABoxd const &leafAABox = bspLeaf->poly().aaBox();
AABoxd const &leafAABox = subspace->poly().aaBox();
if(parm.box)
{
if(leafAABox.maxX < parm.box->minX ||
Expand All @@ -2390,32 +2388,32 @@ static int blockmapCellBspLeafsIterator(void *object, void *context)
}

// Action the callback.
if(int result = parm.callback(bspLeaf, parm.context))
if(int result = parm.callback(subspace, parm.context))
return result; // Stop iteration.
}

return false; // Continue iteration.
}

int Map::bspLeafBoxIterator(AABoxd const &box, int (*callback) (BspLeaf *, void *),
void *context) const
int Map::subspaceBoxIterator(AABoxd const &box, int (*callback) (ConvexSubspace *, void *),
void *context) const
{
if(!d->bspLeafBlockmap.isNull())
if(!d->subspaceBlockmap.isNull())
{
static int localValidCount = 0;
// This is only used here.
localValidCount++;

blockmapcellbspleafsiterator_params_t parm; zap(parm);
blockmapcellsubspacesiterator_params_t parm; zap(parm);
parm.localValidCount = localValidCount;
parm.callback = callback;
parm.context = context;
parm.box = &box;

return d->bspLeafBlockmap->iterate(box, blockmapCellBspLeafsIterator, &parm);
return d->subspaceBlockmap->iterate(box, blockmapCellSubspacesIterator, &parm);
}
/// @throw MissingBlockmapError The BSP leaf blockmap is not yet initialized.
throw MissingBlockmapError("Map::bspLeafBoxIterator", "BSP leaf blockmap is not initialized");
/// @throw MissingBlockmapError The subspace blockmap is not yet initialized.
throw MissingBlockmapError("Map::subspaceBoxIterator", "Convex subspace blockmap is not initialized");
}

int Map::mobjTouchedLineIterator(mobj_t *mo, int (*callback) (Line *, void *),
Expand Down Expand Up @@ -3484,9 +3482,9 @@ D_CMD(InspectMap)
LOG_SCR_MSG(_E(l) "BSP: " _E(.) _E(i)) << bspTreeSummary(map);
}

if(!map.bspLeafBlockmap().isNull())
if(!map.subspaceBlockmap().isNull())
{
LOG_SCR_MSG(_E(l) "BSP leaf blockmap: " _E(.) _E(i)) << map.bspLeafBlockmap().dimensions().asText();
LOG_SCR_MSG(_E(l) "Subspace blockmap: " _E(.) _E(i)) << map.subspaceBlockmap().dimensions().asText();
}
if(!map.lineBlockmap().isNull())
{
Expand Down Expand Up @@ -4045,8 +4043,8 @@ bool Map::endEditing()
plane->updateSoundEmitterOrigin();
}

// We can now initialize the BSP leaf blockmap.
d->initBspLeafBlockmap();
// We can now initialize the convex subspace blockmap.
d->initSubspaceBlockmap();

// Prepare the thinker lists.
d->thinkers.reset(new Thinkers);
Expand Down

0 comments on commit f501d7e

Please sign in to comment.