From 5e2bd632f0da20c05790255a6fd31ec79176c81c Mon Sep 17 00:00:00 2001 From: danij Date: Wed, 9 Oct 2013 06:10:06 +0100 Subject: [PATCH] Refactor|World|Blockmap: BlockmapCellBlock is now inclusive-exclusive Previously an inclusive-inclusive representation was used. Although this representation is immediately easier to use when translating a map space AABB, it means one has to be aware of how this translates to a blockmap traversal. A better approach is an inclusive-exclusive range for traversal and account for this when converting an AABB to a CellBlock. Also began the process of unraveling some of the more complicated Blockmap traversal logics ahead of replacing this API with a better, iterator based design. --- .../client/include/render/blockmapvisual.h | 8 +- doomsday/client/src/render/blockmapvisual.cpp | 106 ++-- doomsday/client/src/world/blockmap.cpp | 72 ++- doomsday/client/src/world/contactspreader.cpp | 4 +- doomsday/client/src/world/map.cpp | 493 +++++++----------- doomsday/client/src/world/p_mobj.cpp | 5 +- 6 files changed, 276 insertions(+), 412 deletions(-) diff --git a/doomsday/client/include/render/blockmapvisual.h b/doomsday/client/include/render/blockmapvisual.h index 4933fd5eea..80a907ade5 100644 --- a/doomsday/client/include/render/blockmapvisual.h +++ b/doomsday/client/include/render/blockmapvisual.h @@ -1,4 +1,4 @@ -/** @file render/blockmapvisual.h Graphical Blockmap Visual. +/** @file blockmapvisual.h Blockmap debug visualizer. * * @authors Copyright © 2003-2013 Jaakko Keränen * @authors Copyright © 2006-2013 Daniel Swanson @@ -18,8 +18,8 @@ * 02110-1301 USA */ -#ifndef DENG_RENDER_BLOCKMAPVISUAL_H -#define DENG_RENDER_BLOCKMAPVISUAL_H +#ifndef DENG_CLIENT_RENDER_BLOCKMAPVISUAL_H +#define DENG_CLIENT_RENDER_BLOCKMAPVISUAL_H #include @@ -31,4 +31,4 @@ DENG_EXTERN_C float bmapDebugSize; ///< cvar */ DENG_EXTERN_C void Rend_BlockmapDebug(); -#endif // DENG_RENDER_BLOCKMAPVISUAL_H +#endif // DENG_CLIENT_RENDER_BLOCKMAPVISUAL_H diff --git a/doomsday/client/src/render/blockmapvisual.cpp b/doomsday/client/src/render/blockmapvisual.cpp index 41be3f8406..7dff356514 100644 --- a/doomsday/client/src/render/blockmapvisual.cpp +++ b/doomsday/client/src/render/blockmapvisual.cpp @@ -203,7 +203,7 @@ static int drawCellBspLeafs(Blockmap const &bmap, BlockmapCell const &cell, void static void drawBackground(Blockmap const &bmap) { - BlockmapCell const &bmapDimensions = bmap.dimensions(); + BlockmapCell const &dimensions = bmap.dimensions(); // Scale modelview matrix so we can express cell geometry // using a cell-sized unit coordinate space. @@ -216,10 +216,10 @@ static void drawBackground(Blockmap const &bmap) */ glColor4f(.25f, .25f, .25f, .66f); glBegin(GL_QUADS); - glVertex2f(0, 0); - glVertex2f(bmapDimensions.x, 0); - glVertex2f(bmapDimensions.x, bmapDimensions.y); - glVertex2f(0, bmapDimensions.y); + glVertex2f(0, 0); + glVertex2f(dimensions.x, 0); + glVertex2f(dimensions.x, dimensions.y); + glVertex2f(0, dimensions.y); glEnd(); /* @@ -227,8 +227,8 @@ static void drawBackground(Blockmap const &bmap) */ glColor4f(0, 0, 0, .95f); BlockmapCell cell; - for(cell.y = 0; cell.y < bmapDimensions.y; ++cell.y) - for(cell.x = 0; cell.x < bmapDimensions.x; ++cell.x) + for(cell.y = 0; cell.y < dimensions.y; ++cell.y) + for(cell.x = 0; cell.x < dimensions.x; ++cell.x) { if(bmap.cellElementCount(cell)) continue; @@ -245,10 +245,8 @@ static void drawBackground(Blockmap const &bmap) glPopMatrix(); } -static void drawCellInfo(Point2Raw const *_origin, char const *info) +static void drawCellInfo(Vector2d const &origin_, char const *info) { - DENG_ASSERT(_origin != 0); - glEnable(GL_TEXTURE_2D); FR_SetFont(fontFixed); @@ -259,8 +257,7 @@ static void drawCellInfo(Point2Raw const *_origin, char const *info) Size2Raw size(16 + FR_TextWidth(info), 16 + FR_SingleLineHeight(info)); - Point2Raw origin = *_origin; - + Point2Raw origin(origin_.x, origin_.y); origin.x -= size.width / 2; UI_GradientEx(&origin, &size, 6, UI_Color(UIC_BG_MEDIUM), UI_Color(UIC_BG_LIGHT), .5f, .5f); UI_DrawRectEx(&origin, &size, 6, false, UI_Color(UIC_BRD_HI), NULL, .5f, -1); @@ -273,13 +270,11 @@ static void drawCellInfo(Point2Raw const *_origin, char const *info) glDisable(GL_TEXTURE_2D); } -static void drawBlockmapInfo(Point2Raw const *_origin, Blockmap const *blockmap) +static void drawBlockmapInfo(Vector2d const &origin_, Blockmap const &blockmap) { - DENG_ASSERT(blockmap != 0); - glEnable(GL_TEXTURE_2D); - Point2Raw origin = *_origin; + Point2Raw origin(origin_.x, origin_.y); FR_SetFont(fontFixed); FR_LoadDefaultAttrib(); @@ -302,48 +297,46 @@ static void drawBlockmapInfo(Point2Raw const *_origin, Blockmap const *blockmap) UI_TextOutEx2("Blockmap", &origin, UI_Color(UIC_TITLE), 1, ALIGN_LEFT, DTF_ONLY_SHADOW); origin.y += th; - Vector2ui const &bmapDimensions = blockmap->dimensions(); + Vector2ui const &bmapDimensions = blockmap.dimensions(); char buf[80]; dd_snprintf(buf, 80, "Dimensions:(%u, %u) #%li", bmapDimensions.x, bmapDimensions.y, (long) bmapDimensions.y * bmapDimensions.x); UI_TextOutEx2(buf, &origin, UI_Color(UIC_TEXT), 1, ALIGN_LEFT, DTF_ONLY_SHADOW); origin.y += th; - dd_snprintf(buf, 80, "Cell dimensions:(%.3f, %.3f)", blockmap->cellWidth(), blockmap->cellHeight()); + dd_snprintf(buf, 80, "Cell dimensions:(%.3f, %.3f)", blockmap.cellWidth(), blockmap.cellHeight()); UI_TextOutEx2(buf, &origin, UI_Color(UIC_TEXT), 1, ALIGN_LEFT, DTF_ONLY_SHADOW); origin.y += th; dd_snprintf(buf, 80, "(%+06.0f, %+06.0f) (%+06.0f, %+06.0f)", - blockmap->bounds().minX, blockmap->bounds().minY, - blockmap->bounds().maxX, blockmap->bounds().maxY); + blockmap.bounds().minX, blockmap.bounds().minY, + blockmap.bounds().maxX, blockmap.bounds().maxY); UI_TextOutEx2(buf, &origin, UI_Color(UIC_TEXT), 1, ALIGN_LEFT, DTF_ONLY_SHADOW); glDisable(GL_TEXTURE_2D); } -static void drawCellInfoBox(Blockmap const *blockmap, Point2Raw const *origin, +static void drawCellInfoBox(Vector2d const &origin, Blockmap const &blockmap, char const *objectTypeName, BlockmapCell const &cell) { - uint count = blockmap->cellElementCount(cell); - char info[160]; - - dd_snprintf(info, 160, "Cell:(%u, %u) %s:#%u", cell.x, cell.y, objectTypeName, count); + uint count = blockmap.cellElementCount(cell); + char info[160]; dd_snprintf(info, 160, "Cell:(%u, %u) %s:#%u", cell.x, cell.y, objectTypeName, count); drawCellInfo(origin, info); } /** * @param bmap Blockmap to be rendered. - * @param followMobj Mobj to center/focus the visual on. Can be @c NULL. - * @param cellDrawer Blockmap cell content drawing callback. Can be @a NULL. + * @param followMobj Mobj to center/focus the visual on. Can be @c 0. + * @param cellDrawer Blockmap cell content drawing callback. Can be @c 0. */ static void drawBlockmap(Blockmap const &bmap, mobj_t *followMobj, - int (*cellDrawer) (Blockmap const &bmap, BlockmapCell const &cell, void *context)) + int (*cellDrawer) (Blockmap const &, BlockmapCell const &, void *)) { BlockmapCellBlock vCellBlock; BlockmapCell vCell; BlockmapCell const &dimensions = bmap.dimensions(); - Vector2d const &cellDimensions = bmap.cellDimensions(); + Vector2d const &cellDimensions = bmap.cellDimensions(); if(followMobj) { @@ -389,10 +382,10 @@ static void drawBlockmap(Blockmap const &bmap, mobj_t *followMobj, glBegin(GL_QUADS); BlockmapCell cell; - for(cell.y = vCellBlock.min.y; cell.y <= vCellBlock.max.y; ++cell.y) - for(cell.x = vCellBlock.min.x; cell.x <= vCellBlock.max.x; ++cell.x) + for(cell.y = vCellBlock.min.y; cell.y < vCellBlock.max.y; ++cell.y) + for(cell.x = vCellBlock.min.x; cell.x < vCellBlock.max.x; ++cell.x) { - if(cell.x == vCell.x && cell.y == vCell.y) + if(cell == vCell) { // The cell the followed Mobj is actually in. glColor4f(.66f, .66f, 1, .66f); @@ -403,8 +396,8 @@ static void drawBlockmap(Blockmap const &bmap, mobj_t *followMobj, glColor4f(.33f, .33f, .66f, .33f); } - Vector2d start = cellDimensions * cell; - Vector2d end = start + cellDimensions; + Vector2d const start = cellDimensions * cell; + Vector2d const end = start + cellDimensions; glVertex2d(start.x, start.y); glVertex2d( end.x, start.y); @@ -454,11 +447,12 @@ static void drawBlockmap(Blockmap const &bmap, mobj_t *followMobj, for(cell.y = 0; cell.y < dimensions.y; ++cell.y) for(cell.x = 0; cell.x < dimensions.x; ++cell.x) { - if(cell.x >= vCellBlock.min.x && cell.x <= vCellBlock.max.x && - cell.y >= vCellBlock.min.y && cell.y <= vCellBlock.max.y) - continue; - if(!bmap.cellElementCount(cell)) + if(cell.x >= vCellBlock.min.x && cell.x < vCellBlock.max.x && + cell.y >= vCellBlock.min.y && cell.y < vCellBlock.max.y) + { continue; + } + if(!bmap.cellElementCount(cell)) continue; cellDrawer(bmap, cell, 0/*no params*/); } @@ -466,14 +460,11 @@ static void drawBlockmap(Blockmap const &bmap, mobj_t *followMobj, // Next, the cells within the "touch" range (orange). validCount++; glColor3f(1, .5f, 0); - for(cell.y = vCellBlock.min.y; cell.y <= vCellBlock.max.y; ++cell.y) - for(cell.x = vCellBlock.min.x; cell.x <= vCellBlock.max.x; ++cell.x) + for(cell.y = vCellBlock.min.y; cell.y < vCellBlock.max.y; ++cell.y) + for(cell.x = vCellBlock.min.x; cell.x < vCellBlock.max.x; ++cell.x) { - if(cell == vCell) - continue; - - if(!bmap.cellElementCount(cell)) - continue; + if(cell == vCell) continue; + if(!bmap.cellElementCount(cell)) continue; cellDrawer(bmap, cell, 0/*no params*/); } @@ -521,19 +512,15 @@ static void drawBlockmap(Blockmap const &bmap, mobj_t *followMobj, void Rend_BlockmapDebug() { - int (*cellDrawer) (Blockmap const &blockmap, BlockmapCell const &cell, void *context); - char const *objectTypeName; - mobj_t *followMobj = 0; - Blockmap const *blockmap; - Point2Raw origin; - float scale; - // Disabled? if(!bmapShowDebug || bmapShowDebug > 4) return; if(!App_World().hasMap()) return; - Map &map = App_World().map(); + + Blockmap const *blockmap; + int (*cellDrawer) (Blockmap const &, BlockmapCell const &, void *); + char const *objectTypeName; switch(bmapShowDebug) { default: // Mobjs. @@ -575,10 +562,11 @@ void Rend_BlockmapDebug() glTranslatef((DENG_GAMEVIEW_WIDTH / 2), (DENG_GAMEVIEW_HEIGHT / 2), 0); // Uniform scaling factor for this visual. - scale = bmapDebugSize / de::max(DENG_GAMEVIEW_HEIGHT / 100, 1); + float scale = bmapDebugSize / de::max(DENG_GAMEVIEW_HEIGHT / 100, 1); glScalef(scale, -scale, 1); // If possible we'll tailor what we draw relative to the viewPlayer. + mobj_t *followMobj = 0; if(viewPlayer && viewPlayer->shared.mo) followMobj = viewPlayer->shared.mo; @@ -603,16 +591,14 @@ void Rend_BlockmapDebug() BlockmapCell cell = blockmap->toCell(followMobj->origin, &didClip); if(!didClip) { - origin.x = DENG_GAMEVIEW_WIDTH / 2; - origin.y = 30; - drawCellInfoBox(blockmap, &origin, objectTypeName, cell); + drawCellInfoBox(Vector2d(DENG_GAMEVIEW_WIDTH / 2, 30), *blockmap, + objectTypeName, cell); } } // About the Blockmap itself. - origin.x = DENG_GAMEVIEW_WIDTH - 10; - origin.y = DENG_GAMEVIEW_HEIGHT - 10; - drawBlockmapInfo(&origin, blockmap); + drawBlockmapInfo(Vector2d(DENG_GAMEVIEW_WIDTH - 10, DENG_GAMEVIEW_HEIGHT - 10), + *blockmap); glMatrixMode(GL_PROJECTION); glPopMatrix(); diff --git a/doomsday/client/src/world/blockmap.cpp b/doomsday/client/src/world/blockmap.cpp index 60a28623a9..7fb706fd23 100644 --- a/doomsday/client/src/world/blockmap.cpp +++ b/doomsday/client/src/world/blockmap.cpp @@ -221,7 +221,7 @@ DENG2_PIMPL(Blockmap) newNode(Cell(0, 0), ceilPow2(de::max(dimensions.x, dimensions.y))); } - inline int toCellIndex(uint cellX, uint cellY) const + inline int toCellIndex(uint cellX, uint cellY) { return int(cellY * dimensions.x + cellX); } @@ -236,7 +236,7 @@ DENG2_PIMPL(Blockmap) * * @return Translated blockmap cell X coordinate. */ - uint toCellX(coord_t x, bool &didClip) const + uint toCellX(coord_t x, bool &didClip) { didClip = false; if(x < bounds.minX) @@ -262,7 +262,7 @@ DENG2_PIMPL(Blockmap) * * @return Translated blockmap cell Y coordinate. */ - uint toCellY(coord_t y, bool &didClip) const + uint toCellY(coord_t y, bool &didClip) { didClip = false; if(y < bounds.minY) @@ -278,6 +278,20 @@ DENG2_PIMPL(Blockmap) return uint((y - bounds.minY) / cellDimensions.y); } + void clipCell(Cell &cell, bool &didClip) + { + if(cell.x > dimensions.x) + { + cell.x = dimensions.x; + didClip = true; + } + if(cell.y > dimensions.y) + { + cell.y = dimensions.y; + didClip = true; + } + } + /** * Clip the cell coordinates in @a block vs the dimensions of this gridmap * so that they are inside the boundary this defines. @@ -286,30 +300,12 @@ DENG2_PIMPL(Blockmap) * * @return @c true iff the block coordinates were changed. */ - bool clipBlock(CellBlock &block) const + bool clipBlock(CellBlock &block) { - bool didClip = false; - if(block.min.x >= dimensions.x) - { - block.min.x = dimensions.x - 1; - didClip = true; - } - if(block.min.y >= dimensions.y) - { - block.min.y = dimensions.y - 1; - didClip = true; - } - if(block.max.x >= dimensions.x) - { - block.max.x = dimensions.x - 1; - didClip = true; - } - if(block.max.y >= dimensions.y) - { - block.max.y = dimensions.y - 1; - didClip = true; - } - return didClip; + bool didClipMin, didClipMax; + clipCell(block.min, didClipMin); + clipCell(block.max, didClipMax); + return didClipMin | didClipMax; } Node *newNode(Cell const &at, uint size) @@ -318,10 +314,9 @@ DENG2_PIMPL(Blockmap) return &nodes.last(); } - Node *findLeaf(Node *node, Cell const &at, bool canCreate) + Node *findLeaf(Node *node, Cell const &at, bool canSubdivide) { - if(node->isLeaf()) - return node; + if(node->isLeaf()) return node; // Into which quadrant do we need to descend? Node::Quadrant q = node->quadrant(at); @@ -330,7 +325,7 @@ DENG2_PIMPL(Blockmap) Node **childAdr = &node->children[q]; if(!*childAdr) { - if(!canCreate) return 0; + if(!canSubdivide) return 0; // Subdivide the space. uint const subSize = node->size >> 1; @@ -353,7 +348,7 @@ DENG2_PIMPL(Blockmap) } } - return findLeaf(*childAdr, at, canCreate); + return findLeaf(*childAdr, at, canSubdivide); } inline Node *findLeaf(Cell const &at, bool canCreate = false) @@ -442,6 +437,7 @@ BlockmapCellBlock Blockmap::toCellBlock(AABoxd const &box, bool *retDidClip) con { bool didClipMin, didClipMax; CellBlock block(toCell(box.min, &didClipMin), toCell(box.max, &didClipMax)); + block.max += Vector2ui(1, 1); // CellBlock is inclusive-exclusive. if(retDidClip) *retDidClip = didClipMin | didClipMax; return block; } @@ -467,8 +463,8 @@ bool Blockmap::link(CellBlock const &cellBlock_, void *elem) d->clipBlock(cellBlock); Cell cell; - for(cell.y = cellBlock.min.y; cell.y <= cellBlock.max.y; ++cell.y) - for(cell.x = cellBlock.min.x; cell.x <= cellBlock.max.x; ++cell.x) + for(cell.y = cellBlock.min.y; cell.y < cellBlock.max.y; ++cell.y) + for(cell.x = cellBlock.min.x; cell.x < cellBlock.max.x; ++cell.x) { Instance::Node *node = d->findLeaf(cell); if(!node) continue; @@ -506,8 +502,8 @@ bool Blockmap::unlink(CellBlock const &cellBlock_, void *elem) d->clipBlock(cellBlock); Cell cell; - for(cell.y = cellBlock.min.y; cell.y <= cellBlock.max.y; ++cell.y) - for(cell.x = cellBlock.min.x; cell.x <= cellBlock.max.x; ++cell.x) + for(cell.y = cellBlock.min.y; cell.y < cellBlock.max.y; ++cell.y) + for(cell.x = cellBlock.min.x; cell.x < cellBlock.max.x; ++cell.x) { Instance::Node *node = d->findLeaf(cell); if(!node) continue; @@ -580,8 +576,8 @@ int Blockmap::iterate(CellBlock const &cellBlock_, int (*callback) (void *, void d->clipBlock(cellBlock); Cell cell; - for(cell.y = cellBlock.min.y; cell.y <= cellBlock.max.y; ++cell.y) - for(cell.x = cellBlock.min.x; cell.x <= cellBlock.max.x; ++cell.x) + for(cell.y = cellBlock.min.y; cell.y < cellBlock.max.y; ++cell.y) + for(cell.x = cellBlock.min.x; cell.x < cellBlock.max.x; ++cell.x) { if(int result = iterate(cell, callback, context)) return result; @@ -612,7 +608,7 @@ void Blockmap::drawDebugVisual() const if(!node.leafData) continue; Vector2f const topLeft = node.cell * UNIT_SIZE; - Vector2f const bottomRight = topLeft + UNIT_SIZE; + Vector2f const bottomRight = topLeft + Vector2f(UNIT_SIZE, UNIT_SIZE); glBegin(GL_LINE_LOOP); glVertex2f(topLeft.x, topLeft.y); diff --git a/doomsday/client/src/world/contactspreader.cpp b/doomsday/client/src/world/contactspreader.cpp index 263f01d220..3d618bf194 100644 --- a/doomsday/client/src/world/contactspreader.cpp +++ b/doomsday/client/src/world/contactspreader.cpp @@ -87,8 +87,8 @@ struct ContactSpreader BlockmapCellBlock const cellBlock = _blockmap.toCellBlock(box); BlockmapCell cell; - for(cell.y = cellBlock.min.y; cell.y <= cellBlock.max.y; ++cell.y) - for(cell.x = cellBlock.min.x; cell.x <= cellBlock.max.x; ++cell.x) + for(cell.y = cellBlock.min.y; cell.y < cellBlock.max.y; ++cell.y) + for(cell.x = cellBlock.min.x; cell.x < cellBlock.max.x; ++cell.x) { if(_spreadBlocks) { diff --git a/doomsday/client/src/world/map.cpp b/doomsday/client/src/world/map.cpp index c5f4eb22b1..1907329c1c 100644 --- a/doomsday/client/src/world/map.cpp +++ b/doomsday/client/src/world/map.cpp @@ -85,7 +85,7 @@ #define DO_LINKS(it, end, _Type) { \ for(it = linkStore; it < end; it++) \ { \ - result = callback(reinterpret_cast<_Type>(*it), parameters); \ + result = callback(reinterpret_cast<_Type>(*it), context); \ if(result) break; \ } \ } @@ -717,11 +717,11 @@ DENG2_OBSERVES(bsp::Partitioner, UnclosedSectorFound) Vector2d const &cellDimensions = lineBlockmap->cellDimensions(); // Determine the block of cells we'll be working within. - Blockmap::CellBlock cellBlock = lineBlockmap->toCellBlock(line.aaBox()); + BlockmapCellBlock cellBlock = lineBlockmap->toCellBlock(line.aaBox()); - Blockmap::Cell cell; - for(cell.y = cellBlock.min.y; cell.y <= cellBlock.max.y; ++cell.y) - for(cell.x = cellBlock.min.x; cell.x <= cellBlock.max.x; ++cell.x) + BlockmapCell cell; + for(cell.y = cellBlock.min.y; cell.y < cellBlock.max.y; ++cell.y) + for(cell.x = cellBlock.min.x; cell.x < cellBlock.max.x; ++cell.x) { if(line.slopeType() == ST_VERTICAL || line.slopeType() == ST_HORIZONTAL) @@ -781,13 +781,13 @@ DENG2_OBSERVES(bsp::Partitioner, UnclosedSectorFound) bool unlinkMobjInBlockmap(mobj_t &mo) { - Blockmap::Cell cell = mobjBlockmap->toCell(mo.origin); + BlockmapCell cell = mobjBlockmap->toCell(mo.origin); return mobjBlockmap->unlink(cell, &mo); } void linkMobjInBlockmap(mobj_t &mo) { - Blockmap::Cell cell = mobjBlockmap->toCell(mo.origin); + BlockmapCell cell = mobjBlockmap->toCell(mo.origin); mobjBlockmap->link(cell, &mo); } @@ -923,20 +923,14 @@ DENG2_OBSERVES(bsp::Partitioner, UnclosedSectorFound) void unlinkPolyobjInBlockmap(Polyobj &polyobj) { - Blockmap::CellBlock cellBlock = polyobjBlockmap->toCellBlock(polyobj.aaBox); + BlockmapCellBlock cellBlock = polyobjBlockmap->toCellBlock(polyobj.aaBox); polyobjBlockmap->unlink(cellBlock, &polyobj); } void linkPolyobjInBlockmap(Polyobj &polyobj) { - Blockmap::CellBlock cellBlock = polyobjBlockmap->toCellBlock(polyobj.aaBox); - - Blockmap::Cell cell; - for(cell.y = cellBlock.min.y; cell.y <= cellBlock.max.y; ++cell.y) - for(cell.x = cellBlock.min.x; cell.x <= cellBlock.max.x; ++cell.x) - { - polyobjBlockmap->link(cell, &polyobj); - } + BlockmapCellBlock cellBlock = polyobjBlockmap->toCellBlock(polyobj.aaBox); + polyobjBlockmap->link(cellBlock, &polyobj); } /** @@ -974,14 +968,8 @@ DENG2_OBSERVES(bsp::Partitioner, UnclosedSectorFound) // BspLeafs without sector clusters don't get in. if(!bspLeaf.hasCluster()) return; - Blockmap::CellBlock cellBlock = bspLeafBlockmap->toCellBlock(bspLeaf.poly().aaBox()); - - Blockmap::Cell cell; - for(cell.y = cellBlock.min.y; cell.y <= cellBlock.max.y; ++cell.y) - for(cell.x = cellBlock.min.x; cell.x <= cellBlock.max.x; ++cell.x) - { - bspLeafBlockmap->link(cell, &bspLeaf); - } + BlockmapCellBlock cellBlock = bspLeafBlockmap->toCellBlock(bspLeaf.poly().aaBox()); + bspLeafBlockmap->link(cellBlock, &bspLeaf); } #ifdef __CLIENT__ @@ -1728,57 +1716,41 @@ Blockmap const &Map::bspLeafBlockmap() const struct bmapmoiterparams_t { int localValidCount; - int (*func) (mobj_t *, void *); - void *parms; + int (*callback) (mobj_t *, void *); + void *context; }; static int blockmapCellMobjsIterator(void *object, void *context) { - mobj_t *mobj = (mobj_t *)object; - bmapmoiterparams_t *args = (bmapmoiterparams_t *) context; - if(mobj->validCount != args->localValidCount) - { - int result; + mobj_t *mobj = static_cast(object); + bmapmoiterparams_t &parm = *static_cast(context); + if(mobj->validCount != parm.localValidCount) + { // This mobj has now been processed for the current iteration. - mobj->validCount = args->localValidCount; + mobj->validCount = parm.localValidCount; // Action the callback. - result = args->func(mobj, args->parms); - if(result) return result; // Stop iteration. + if(int result = parm.callback(mobj, parm.context)) + return result; // Stop iteration. } - return false; // Continue iteration. -} - -static int iterateCellMobjs(Blockmap &mobjBlockmap, Blockmap::Cell const &cell, - int (*callback) (mobj_t *, void *), void *context = 0) -{ - bmapmoiterparams_t args; - args.localValidCount = validCount; - args.func = callback; - args.parms = context; - - return mobjBlockmap.iterate(cell, blockmapCellMobjsIterator, (void *) &args); -} -static int iterateCellBlockMobjs(Blockmap &mobjBlockmap, Blockmap::CellBlock const &cellBlock, - int (*callback) (mobj_t *, void *), void *context = 0) -{ - bmapmoiterparams_t args; - args.localValidCount = validCount; - args.func = callback; - args.parms = context; - - return mobjBlockmap.iterate(cellBlock, blockmapCellMobjsIterator, (void *) &args); + return false; // Continue iteration. } int Map::mobjBoxIterator(AABoxd const &box, int (*callback) (mobj_t *, void *), - void *parameters) const + void *context) const { if(!d->mobjBlockmap.isNull()) { - Blockmap::CellBlock cellBlock = d->mobjBlockmap->toCellBlock(box); - return iterateCellBlockMobjs(*d->mobjBlockmap, cellBlock, callback, parameters); + BlockmapCellBlock cellBlock = d->mobjBlockmap->toCellBlock(box); + + bmapmoiterparams_t parm; zap(parm); + parm.localValidCount = validCount; + parm.callback = callback; + parm.context = context; + + return d->mobjBlockmap->iterate(cellBlock, blockmapCellMobjsIterator, &parm); } /// @throw MissingBlockmapError The mobj blockmap is not yet initialized. throw MissingBlockmapError("Map::mobjBoxIterator", "Mobj blockmap is not initialized"); @@ -1788,127 +1760,71 @@ struct bmapiterparams_t { int localValidCount; int (*callback) (Line *, void *); - void *parms; + void *context; }; static int blockmapCellLinesIterator(void *mapElement, void *context) { Line *line = static_cast(mapElement); - bmapiterparams_t *parms = static_cast(context); + bmapiterparams_t &parm = *static_cast(context); - if(line->validCount() != parms->localValidCount) + if(line->validCount() != parm.localValidCount) { - int result; - // This line has now been processed for the current iteration. - line->setValidCount(parms->localValidCount); + line->setValidCount(parm.localValidCount); // Action the callback. - result = parms->callback(line, parms->parms); - if(result) return result; // Stop iteration. + if(int result = parm.callback(line, parm.context)) + return result; // Stop iteration. } return false; // Continue iteration. } -static int iterateCellLines(Blockmap &lineBlockmap, Blockmap::Cell const &cell, - int (*callback) (Line *, void *), void *context = 0) -{ - bmapiterparams_t parms; - parms.localValidCount = validCount; - parms.callback = callback; - parms.parms = context; - - return lineBlockmap.iterate(cell, blockmapCellLinesIterator, (void *)&parms); -} - -static int iterateCellBlockLines(Blockmap &lineBlockmap, Blockmap::CellBlock const &cellBlock, - int (*callback) (Line *, void *), void *context = 0) -{ - bmapiterparams_t parms; - parms.localValidCount = validCount; - parms.callback = callback; - parms.parms = context; - - return lineBlockmap.iterate(cellBlock, blockmapCellLinesIterator, (void *) &parms); -} - struct bmapbspleafiterateparams_t { AABoxd const *box; Sector *sector; int localValidCount; - int (*func) (BspLeaf *, void *); - void *parms; + int (*callback) (BspLeaf *, void *); + void *context; }; static int blockmapCellBspLeafsIterator(void *object, void *context) { - BspLeaf *bspLeaf = (BspLeaf *)object; - bmapbspleafiterateparams_t *args = (bmapbspleafiterateparams_t *) context; - if(bspLeaf->validCount() != args->localValidCount) - { - bool ok = true; + BspLeaf *bspLeaf = static_cast(object); + bmapbspleafiterateparams_t &parm = *static_cast(context); + if(bspLeaf->validCount() != parm.localValidCount) + { // This BspLeaf has now been processed for the current iteration. - bspLeaf->setValidCount(args->localValidCount); + bspLeaf->setValidCount(parm.localValidCount); // Check the sector restriction. - if(args->sector && bspLeaf->sectorPtr() != args->sector) - ok = false; + bool ok = !(parm.sector && bspLeaf->sectorPtr() != parm.sector); // Check the bounds. AABoxd const &leafAABox = bspLeaf->poly().aaBox(); - if(args->box && - (leafAABox.maxX < args->box->minX || - leafAABox.minX > args->box->maxX || - leafAABox.minY > args->box->maxY || - leafAABox.maxY < args->box->minY)) + if(parm.box && + (leafAABox.maxX < parm.box->minX || + leafAABox.minX > parm.box->maxX || + leafAABox.minY > parm.box->maxY || + leafAABox.maxY < parm.box->minY)) ok = false; if(ok) { // Action the callback. - int result = args->func(bspLeaf, args->parms); - if(result) return result; // Stop iteration. + if(int result = parm.callback(bspLeaf, parm.context)) + return result; // Stop iteration. } } - return false; // Continue iteration. -} -/* -static int iterateCellBspLeafs(Blockmap &bspLeafBlockmap, Blockmap::const_Cell cell, - Sector *sector, AABoxd const &box, int localValidCount, - int (*callback) (BspLeaf *, void *), void *context = 0) -{ - bmapbspleafiterateparams_t args; - args.localValidCount = localValidCount; - args.func = callback; - args.param = context; - args.sector = sector; - args.box = &box; - - return bspLeafBlockmap.iterateCellObjects(cell, blockmapCellBspLeafsIterator, (void*)&args); -} -*/ - -static int iterateBlockBspLeafs(Blockmap &bspLeafBlockmap, - Blockmap::CellBlock const &cellBlock, Sector *sector, AABoxd const &box, - int localValidCount, - int (*callback) (BspLeaf *, void *), void *context = 0) -{ - bmapbspleafiterateparams_t args; - args.localValidCount = localValidCount; - args.func = callback; - args.parms = context; - args.sector = sector; - args.box = &box; - - return bspLeafBlockmap.iterate(cellBlock, blockmapCellBspLeafsIterator, (void *) &args); + return false; // Continue iteration. } int Map::bspLeafBoxIterator(AABoxd const &box, Sector *sector, - int (*callback) (BspLeaf *, void *), void *parameters) const + int (*callback) (BspLeaf *, void *), void *context) const { if(!d->bspLeafBlockmap.isNull()) { @@ -1916,16 +1832,22 @@ int Map::bspLeafBoxIterator(AABoxd const &box, Sector *sector, // This is only used here. localValidCount++; - Blockmap::CellBlock cellBlock = d->bspLeafBlockmap->toCellBlock(box); - return iterateBlockBspLeafs(*d->bspLeafBlockmap, cellBlock, sector, box, - localValidCount, callback, parameters); + bmapbspleafiterateparams_t parm; + parm.localValidCount = localValidCount; + parm.callback = callback; + parm.context = context; + parm.sector = sector; + parm.box = &box; + + BlockmapCellBlock cellBlock = d->bspLeafBlockmap->toCellBlock(box); + return d->bspLeafBlockmap->iterate(cellBlock, blockmapCellBspLeafsIterator, &parm); } /// @throw MissingBlockmapError The BSP leaf blockmap is not yet initialized. throw MissingBlockmapError("Map::bspLeafBoxIterator", "BSP leaf blockmap is not initialized"); } int Map::mobjTouchedLineIterator(mobj_t *mo, int (*callback) (Line *, void *), - void *parameters) const + void *context) const { void *linkStore[MAXLINKED]; void **end = linkStore, **it; @@ -1939,13 +1861,13 @@ int Map::mobjTouchedLineIterator(mobj_t *mo, int (*callback) (Line *, void *), nix = tn[nix].next) *end++ = tn[nix].ptr; - DO_LINKS(it, end, Line*); + DO_LINKS(it, end, Line *); } return result; } int Map::mobjTouchedSectorIterator(mobj_t *mo, int (*callback) (Sector *, void *), - void *parameters) const + void *context) const { int result = false; void *linkStore[MAXLINKED]; @@ -1994,7 +1916,7 @@ int Map::mobjTouchedSectorIterator(mobj_t *mo, int (*callback) (Sector *, void * } int Map::lineTouchingMobjIterator(Line *line, int (*callback) (mobj_t *, void *), - void *parameters) const + void *context) const { void *linkStore[MAXLINKED]; void **end = linkStore; @@ -2016,7 +1938,7 @@ int Map::lineTouchingMobjIterator(Line *line, int (*callback) (mobj_t *, void *) } int Map::sectorTouchingMobjIterator(Sector *sector, - int (*callback) (mobj_t *, void *), void *parameters) const + int (*callback) (mobj_t *, void *), void *context) const { /// @todo Fixme: Remove fixed limit (use QVarLengthArray if necessary). void *linkStore[MAXLINKED]; @@ -2025,11 +1947,13 @@ int Map::sectorTouchingMobjIterator(Sector *sector, // Collate mobjs that obviously are in the sector. for(mobj_t *mo = sector->firstMobj(); mo; mo = mo->sNext) { - if(mo->validCount == validCount) continue; - mo->validCount = validCount; + if(mo->validCount != validCount) + { + mo->validCount = validCount; - DENG_ASSERT(end < &linkStore[MAXLINKED]); - *end++ = mo; + DENG_ASSERT(end < &linkStore[MAXLINKED]); + *end++ = mo; + } } // Collate mobjs linked to the sector's lines. @@ -2041,12 +1965,13 @@ int Map::sectorTouchingMobjIterator(Sector *sector, for(nodeindex_t nix = ln[root].next; nix != root; nix = ln[nix].next) { mobj_t *mo = (mobj_t *) ln[nix].ptr; + if(mo->validCount != validCount) + { + mo->validCount = validCount; - if(mo->validCount == validCount) continue; - mo->validCount = validCount; - - DENG_ASSERT(end < &linkStore[MAXLINKED]); - *end++ = mo; + DENG_ASSERT(end < &linkStore[MAXLINKED]); + *end++ = mo; + } } } @@ -2134,48 +2059,26 @@ void Map::link(Polyobj &polyobj) struct bmappoiterparams_t { int localValidCount; - int (*func) (Polyobj *, void *); - void *parms; + int (*callback) (Polyobj *, void *); + void *context; }; static int blockmapCellPolyobjsIterator(void *object, void *context) { - Polyobj *polyobj = (Polyobj *)object; - bmappoiterparams_t *args = (bmappoiterparams_t *) context; - if(polyobj->validCount != args->localValidCount) - { - int result; + Polyobj *polyobj = static_cast(object); + bmappoiterparams_t &parm = *static_cast(context); + if(polyobj->validCount != parm.localValidCount) + { // This polyobj has now been processed for the current iteration. - polyobj->validCount = args->localValidCount; + polyobj->validCount = parm.localValidCount; // Action the callback. - result = args->func(polyobj, args->parms); - if(result) return result; // Stop iteration. + if(int result = parm.callback(polyobj, parm.context)) + return result; // Stop iteration. } - return false; // Continue iteration. -} -static int iterateCellPolyobjs(Blockmap &polyobjBlockmap, Blockmap::Cell const &cell, - int (*callback) (Polyobj *, void *), void *context = 0) -{ - bmappoiterparams_t args; - args.localValidCount = validCount; - args.func = callback; - args.parms = context; - - return polyobjBlockmap.iterate(cell, blockmapCellPolyobjsIterator, (void *)&args); -} - -static int iterateCellBlockPolyobjs(Blockmap &polyobjBlockmap, Blockmap::CellBlock const &cellBlock, - int (*callback) (Polyobj *, void *), void *context = 0) -{ - bmappoiterparams_t args; - args.localValidCount = validCount; - args.func = callback; - args.parms = context; - - return polyobjBlockmap.iterate(cellBlock, blockmapCellPolyobjsIterator, (void*) &args); + return false; // Continue iteration. } int Map::polyobjBoxIterator(AABoxd const &box, @@ -2183,8 +2086,13 @@ int Map::polyobjBoxIterator(AABoxd const &box, { if(!d->polyobjBlockmap.isNull()) { - Blockmap::CellBlock cellBlock = d->polyobjBlockmap->toCellBlock(box); - return iterateCellBlockPolyobjs(*d->polyobjBlockmap, cellBlock, callback, context); + bmappoiterparams_t parm; zap(parm); + parm.localValidCount = validCount; + parm.callback = callback; + parm.context = context; + + BlockmapCellBlock cellBlock = d->polyobjBlockmap->toCellBlock(box); + return d->polyobjBlockmap->iterate(cellBlock, blockmapCellPolyobjsIterator, &parm); } /// @throw MissingBlockmapError The polyobj blockmap is not yet initialized. throw MissingBlockmapError("Map::polyobjBoxIterator", "Polyobj blockmap is not initialized"); @@ -2192,57 +2100,26 @@ int Map::polyobjBoxIterator(AABoxd const &box, struct poiterparams_t { - int (*func) (Line *, void *); - void *parms; + int (*callback) (Line *, void *); + void *context; }; -static int polyobjLineIterator(Polyobj *po, void* context) +static int polyobjLineIterator(Polyobj *po, void *context = 0) { - poiterparams_t *args = (poiterparams_t *) context; + poiterparams_t &parm = *static_cast(context); + foreach(Line *line, po->lines()) { - if(line->validCount() == validCount) - continue; + if(line->validCount() != validCount) + { + line->setValidCount(validCount); - line->setValidCount(validCount); - int result = args->func(line, args->parms); - if(result) return result; + if(int result = parm.callback(line, parm.context)) + return result; + } } - return false; // Continue iteration. -} - -/* -static int iterateCellPolyobjLineIterator(Blockmap &polyobjBlockmap, const_BlockmapCell cell, - int (*callback) (Line *, void *), void *context = 0) -{ - poiterparams_t poargs; - poargs.func = callback; - poargs.param = context; - - bmappoiterparams_t args; - args.localValidCount = validCount; - args.func = PTR_PolyobjLines; - args.param = &poargs; - - return Blockmap_IterateCellObjects(&polyobjBlockmap, cell, - blockmapCellPolyobjsIterator, &args); -} -*/ - -static int iterateBlockPolyobjLines(Blockmap &polyobjBlockmap, - Blockmap::CellBlock const &cellBlock, - int (*callback) (Line *, void *), void *context = 0) -{ - poiterparams_t poargs; - poargs.func = callback; - poargs.parms = context; - bmappoiterparams_t args; - args.localValidCount = validCount; - args.func = polyobjLineIterator; - args.parms = &poargs; - - return polyobjBlockmap.iterate(cellBlock, blockmapCellPolyobjsIterator, (void*) &args); + return false; // Continue iteration. } int Map::lineBoxIterator(AABoxd const &box, int flags, @@ -2255,9 +2132,17 @@ int Map::lineBoxIterator(AABoxd const &box, int flags, /// @throw MissingBlockmapError The polyobj blockmap is not yet initialized. throw MissingBlockmapError("Map::lineBoxIterator", "Polyobj blockmap is not initialized"); - Blockmap::CellBlock cellBlock = d->polyobjBlockmap->toCellBlock(box); - if(int result = iterateBlockPolyobjLines(*d->polyobjBlockmap, cellBlock, - callback, context)) + poiterparams_t poItParm; zap(poItParm); + poItParm.callback = callback; + poItParm.context = context; + + bmappoiterparams_t parm; zap(parm); + parm.localValidCount = validCount; + parm.callback = polyobjLineIterator; + parm.context = &poItParm; + + BlockmapCellBlock cellBlock = d->polyobjBlockmap->toCellBlock(box); + if(int result = d->polyobjBlockmap->iterate(cellBlock, blockmapCellPolyobjsIterator, &parm)) return result; } @@ -2268,17 +2153,22 @@ int Map::lineBoxIterator(AABoxd const &box, int flags, /// @throw MissingBlockmapError The line blockmap is not yet initialized. throw MissingBlockmapError("Map::lineBoxIterator", "Line blockmap is not initialized"); - Blockmap::CellBlock cellBlock = d->lineBlockmap->toCellBlock(box); - if(int result = iterateCellBlockLines(*d->lineBlockmap, cellBlock, callback, context)) + bmapiterparams_t parm; zap(parm); + parm.localValidCount = validCount; + parm.callback = callback; + parm.context = context; + + BlockmapCellBlock cellBlock = d->lineBlockmap->toCellBlock(box); + if(int result = d->lineBlockmap->iterate(cellBlock, blockmapCellLinesIterator, &parm)) return result; } return 0; // Continue iteration. } -static int traverseCellPath2(Blockmap &bmap, Blockmap::Cell const &fromCell, - Blockmap::Cell const &toCell, Vector2d const &from, Vector2d const &to, - int (*callback) (Blockmap::Cell const &cell, void *parameters), void *parameters) +static int traverseCellPath2(Blockmap &bmap, BlockmapCell const &fromCell, + BlockmapCell const &toCell, Vector2d const &from, Vector2d const &to, + int (*callback) (BlockmapCell const &, void *), void *context) { Vector2i stepDir; coord_t frac; @@ -2287,69 +2177,68 @@ static int traverseCellPath2(Blockmap &bmap, Blockmap::Cell const &fromCell, if(toCell.x > fromCell.x) { stepDir.x = 1; - frac = from.x / bmap.cellWidth(); - frac = 1 - (frac - int( frac )); - delta.y = (to.y - from.y) / de::abs(to.x - from.x); + frac = from.x / bmap.cellWidth(); + frac = 1 - (frac - int( frac )); + delta.y = (to.y - from.y) / de::abs(to.x - from.x); } else if(toCell.x < fromCell.x) { stepDir.x = -1; - frac = from.x / bmap.cellWidth(); - frac = (frac - int( frac )); - delta.y = (to.y - from.y) / de::abs(to.x - from.x); + frac = from.x / bmap.cellWidth(); + frac = (frac - int( frac )); + delta.y = (to.y - from.y) / de::abs(to.x - from.x); } else { stepDir.x = 0; - frac = 1; - delta.y = 256; + frac = 1; + delta.y = 256; } intercept.y = from.y / bmap.cellHeight() + frac * delta.y; if(toCell.y > fromCell.y) { stepDir.y = 1; - frac = from.y / bmap.cellHeight(); - frac = 1 - (frac - int( frac )); - delta.x = (to.x - from.x) / de::abs(to.y - from.y); + frac = from.y / bmap.cellHeight(); + frac = 1 - (frac - int( frac )); + delta.x = (to.x - from.x) / de::abs(to.y - from.y); } else if(toCell.y < fromCell.y) { stepDir.y = -1; - frac = from.y / bmap.cellHeight(); - frac = frac - int( frac ); - delta.x = (to.x - from.x) / de::abs(to.y - from.y); + frac = from.y / bmap.cellHeight(); + frac = frac - int( frac ); + delta.x = (to.x - from.x) / de::abs(to.y - from.y); } else { stepDir.y = 0; - frac = 1; - delta.x = 256; + frac = 1; + delta.x = 256; } intercept.x = from.x / bmap.cellWidth() + frac * delta.x; /* * Step through map cells. */ - Blockmap::Cell cell = fromCell; + BlockmapCell cell = fromCell; for(int pass = 0; pass < 64; ++pass) // Prevent a round off error leading us into // an infinite loop... { - int result = callback(cell, parameters); - if(result) return result; // Early out. + if(int result = callback(cell, context)) + return result; // Early out. - if(cell.x == toCell.x && cell.y == toCell.y) - break; + if(cell == toCell) break; /// @todo Replace incremental translation? if(cell.y == uint( intercept.y )) { - cell.x += stepDir.x; + cell.x += stepDir.x; intercept.y += delta.y; } else if(cell.x == uint( intercept.x )) { - cell.y += stepDir.y; + cell.y += stepDir.y; intercept.x += delta.x; } } @@ -2359,7 +2248,7 @@ static int traverseCellPath2(Blockmap &bmap, Blockmap::Cell const &fromCell, static int traversePath(divline_t &traceLine, Blockmap &bmap, Vector2d const &from_, Vector2d const &to_, - int (*callback) (Blockmap::Cell const &cell, void *context), void *context = 0) + int (*callback) (BlockmapCell const &cell, void *context), void *context = 0) { // Constant terms implicitly defined by DOOM's original version of this // algorithm (we must honor these fudge factors for compatibility). @@ -2438,35 +2327,14 @@ static int traversePath(divline_t &traceLine, Blockmap &bmap, } // Clipping already applied above, so we don't need to check it again... - Blockmap::Cell fromCell = bmap.toCell(from); - Blockmap::Cell toCell = bmap.toCell(to); + BlockmapCell fromCell = bmap.toCell(from); + BlockmapCell toCell = bmap.toCell(to); V2d_Subtract(from, from, min); V2d_Subtract(to, to, min); return traverseCellPath2(bmap, fromCell, toCell, from, to, callback, context); } -struct iteratepolyobjlines_params_t -{ - int (*callback) (Line *, void *); - void *parms; -}; - -static int iteratePolyobjLines(Polyobj *po, void *parameters = 0) -{ - iteratepolyobjlines_params_t const *p = (iteratepolyobjlines_params_t *)parameters; - foreach(Line *line, po->lines()) - { - if(line->validCount() == validCount) - continue; - - line->setValidCount(validCount); - int result = p->callback(line, p->parms); - if(result) return result; - } - return false; // Continue iteration. -} - /** * Looks for lines in the given block that intercept the given trace to add * to the intercepts list. @@ -2474,7 +2342,7 @@ static int iteratePolyobjLines(Polyobj *po, void *parameters = 0) * * @return Non-zero if current iteration should stop. */ -static int interceptLinesWorker(Line *line, void * /*parameters*/) +static int interceptLinesWorker(Line *line, void * /*context*/) { divline_t const &traceLos = line->map().traceLine(); int s1, s2; @@ -2513,22 +2381,34 @@ static int interceptLinesWorker(Line *line, void * /*parameters*/) return false; } -static int collectPolyobjLineIntercepts(Blockmap::Cell const &cell, void *parameters) +static int collectPolyobjLineIntercepts(BlockmapCell const &cell, void *context) { - Blockmap *polyobjBlockmap = (Blockmap *)parameters; - iteratepolyobjlines_params_t iplParams; - iplParams.callback = interceptLinesWorker; - iplParams.parms = 0; - return iterateCellPolyobjs(*polyobjBlockmap, cell, iteratePolyobjLines, (void *)&iplParams); + Blockmap &polyobjBlockmap = *static_cast(context); + + poiterparams_t iplParm; zap(iplParm); + iplParm.callback = interceptLinesWorker; + iplParm.context = 0; + + bmappoiterparams_t parm; zap(parm); + parm.localValidCount = validCount; + parm.callback = polyobjLineIterator; + parm.context = &iplParm; + + return polyobjBlockmap.iterate(cell, blockmapCellPolyobjsIterator, &parm); } -static int collectLineIntercepts(Blockmap::Cell const &cell, void *parameters) +static int collectLineIntercepts(BlockmapCell const &cell, void *context) { - Blockmap *lineBlockmap = (Blockmap *)parameters; - return iterateCellLines(*lineBlockmap, cell, interceptLinesWorker); + Blockmap &lineBlockmap = *static_cast(context); + + bmapiterparams_t parm; zap(parm); + parm.localValidCount = validCount; + parm.callback = interceptLinesWorker; + + return lineBlockmap.iterate(cell, blockmapCellLinesIterator, &parm); } -static int interceptMobjsWorker(mobj_t *mo, void * /*parameters*/) +static int interceptMobjsWorker(mobj_t *mo, void * /*context*/) { if(mo->dPlayer && (mo->dPlayer->flags & DDPF_CAMERA)) return false; // $democam: ssshh, keep going, we're not here... @@ -2572,10 +2452,15 @@ static int interceptMobjsWorker(mobj_t *mo, void * /*parameters*/) return false; } -static int collectMobjIntercepts(Blockmap::Cell const &cell, void *parameters) +static int collectMobjIntercepts(BlockmapCell const &cell, void *context) { - Blockmap *mobjBlockmap = (Blockmap *)parameters; - return iterateCellMobjs(*mobjBlockmap, cell, interceptMobjsWorker); + Blockmap &mobjBlockmap = *static_cast(context); + + bmapmoiterparams_t parm; zap(parm); + parm.localValidCount = validCount; + parm.callback = interceptMobjsWorker; + + return mobjBlockmap.iterate(cell, blockmapCellMobjsIterator, &parm); } int Map::pathTraverse(Vector2d const &from, Vector2d const &to, int flags, @@ -2592,16 +2477,16 @@ int Map::pathTraverse(Vector2d const &from, Vector2d const &to, int flags, { traversePath(d->traceLine, *d->polyobjBlockmap, from, to, collectPolyobjLineIntercepts, - (void *)d->polyobjBlockmap.data()); + d->polyobjBlockmap.data()); } traversePath(d->traceLine, *d->lineBlockmap, from, to, collectLineIntercepts, - (void *)d->lineBlockmap.data()); + d->lineBlockmap.data()); } if(flags & PT_ADDMOBJS) { traversePath(d->traceLine, *d->mobjBlockmap, from, to, collectMobjIntercepts, - (void *)d->mobjBlockmap.data()); + d->mobjBlockmap.data()); } // Step #2: Process sorted intercepts. diff --git a/doomsday/client/src/world/p_mobj.cpp b/doomsday/client/src/world/p_mobj.cpp index e60aa49dcf..675e2b6bc1 100644 --- a/doomsday/client/src/world/p_mobj.cpp +++ b/doomsday/client/src/world/p_mobj.cpp @@ -110,10 +110,7 @@ mobj_t *P_MobjCreate(thinkfunc_t function, Vector3d const &origin, angle_t angle mo->ddFlags = ddflags; mo->lumIdx = -1; mo->thinker.function = function; - if(mo->thinker.function) - { - App_World().map().thinkers().add(mo->thinker); - } + App_World().map().thinkers().add(mo->thinker); return mo; }