diff --git a/doomsday/client/include/render/lumobj.h b/doomsday/client/include/render/lumobj.h index bce99f931e..63d1d15bb2 100644 --- a/doomsday/client/include/render/lumobj.h +++ b/doomsday/client/include/render/lumobj.h @@ -156,18 +156,18 @@ texturevariantspecification_t &Rend_LightmapTextureSpec(); /** * Clip lumobj, omni lights in the given BspLeaf. * - * @param bspLeafIdx BspLeaf index in which lights will be clipped. + * @param bspLeaf BspLeaf in which lights will be clipped. */ -void LO_ClipInBspLeaf(int bspLeafIdx); +void LO_ClipInBspLeaf(BspLeaf &bspLeaf); /** * In the situation where a BSP leaf contains both lumobjs and a polyobj, * the lumobjs must be clipped more carefully. Here we check if the line of * sight intersects any of the polyobj hedges that face the camera. * - * @param bspLeafIdx BspLeaf index in which lumobjs will be clipped. + * @param bspLeaf BspLeaf in which lumobjs will be clipped. */ -void LO_ClipInBspLeafBySight(int bspLeafIdx); +void LO_ClipInBspLeafBySight(BspLeaf &bspLeaf); /** * Iterate over all luminous objects within the specified origin range, making diff --git a/doomsday/client/include/render/rend_clip.h b/doomsday/client/include/render/rend_clip.h index 938df2a18d..2362768c3c 100644 --- a/doomsday/client/include/render/rend_clip.h +++ b/doomsday/client/include/render/rend_clip.h @@ -35,7 +35,7 @@ #include -class BspLeaf; +#include "Face" DENG_EXTERN_C int devNoCulling; @@ -63,9 +63,12 @@ int C_IsPointVisible(coord_t x, coord_t y, coord_t height); int C_IsAngleVisible(binangle_t bang); /** - * @return Non-zero if @a bspLeaf might be visible, else @c 0. + * The only requirement is that the half-edges of the polygon form a contiguous + * (and closed) loop. + * + * @return Non-zero if some point of @a poly might be visible, else @c 0. */ -int C_CheckBspLeaf(BspLeaf &bspLeaf); +int C_IsPolyVisible(de::Face const &poly); /** * Add a segment relative to the current viewpoint. diff --git a/doomsday/client/include/world/p_objlink.h b/doomsday/client/include/world/p_objlink.h index 3a1eb6c5db..bee0067eab 100644 --- a/doomsday/client/include/world/p_objlink.h +++ b/doomsday/client/include/world/p_objlink.h @@ -76,8 +76,9 @@ void R_ObjlinkCreate(struct lumobj_s &lumobj); void R_LinkObjs(); /** - * Spread object => BspLeaf links for the given @a BspLeaf. Note that - * all object types will be spread at this time. + * Spread object => BspLeaf links for the given @a BspLeaf. Note that all object + * types will be spread at this time. It is assumed that the BSP leaf is @em not + * degenerate. */ void R_InitForBspLeaf(BspLeaf &bspLeaf); diff --git a/doomsday/client/src/render/lumobj.cpp b/doomsday/client/src/render/lumobj.cpp index c5d35a9d4d..95cdf23722 100644 --- a/doomsday/client/src/render/lumobj.cpp +++ b/doomsday/client/src/render/lumobj.cpp @@ -1145,12 +1145,9 @@ static boolean LOIT_ClipLumObj(void *data, void * /*context*/) return true; // Continue iteration. } -void LO_ClipInBspLeaf(int bspLeafIdx) +void LO_ClipInBspLeaf(BspLeaf &leaf) { - BspLeaf &leaf = *App_World().map().bspLeafs().at(bspLeafIdx); - - if(leaf.isDegenerate()) return; - + DENG2_ASSERT(!leaf.isDegenerate()); iterateBspLeafLumObjs(leaf, LOIT_ClipLumObj); } @@ -1192,12 +1189,9 @@ boolean LOIT_ClipLumObjBySight(void *data, void *context) return true; // Continue iteration. } -void LO_ClipInBspLeafBySight(int bspLeafIdx) +void LO_ClipInBspLeafBySight(BspLeaf &leaf) { - BspLeaf &leaf = *App_World().map().bspLeafs().at(bspLeafIdx); - - if(leaf.isDegenerate()) return; - + DENG_ASSERT(!leaf.isDegenerate()); iterateBspLeafLumObjs(leaf, LOIT_ClipLumObjBySight, &leaf); } diff --git a/doomsday/client/src/render/rend_clip.cpp b/doomsday/client/src/render/rend_clip.cpp index 2d2469586c..1fb8dfad07 100644 --- a/doomsday/client/src/render/rend_clip.cpp +++ b/doomsday/client/src/render/rend_clip.cpp @@ -20,9 +20,7 @@ */ #include -#include -#include #include #include @@ -31,10 +29,6 @@ #include "de_console.h" #include "de_render.h" -#include "Face" - -#include "BspLeaf" - #include "render/rend_clip.h" using namespace de; @@ -963,16 +957,16 @@ int C_IsAngleVisible(binangle_t bang) return true; } -int C_CheckBspLeaf(BspLeaf &leaf) +int C_IsPolyVisible(Face const &poly) { - if(leaf.isDegenerate()) return false; + if(!poly.hedgeCount()) + return false; - if(devNoCulling) return true; + if(devNoCulling) + return true; // Do we need to resize the angle list buffer? - Face const &face = leaf.poly(); - - if(face.hedgeCount() > anglistSize) + if(poly.hedgeCount() > anglistSize) { anglistSize *= 2; if(!anglistSize) @@ -982,17 +976,17 @@ int C_CheckBspLeaf(BspLeaf &leaf) // Find angles to all corners. int n = 0; - HEdge const *hedge = face.hedge(); + HEdge const *hedge = poly.hedge(); do { // Shift for more accuracy. anglist[n++] = bamsAtan2(int( (hedge->origin().y - vOrigin[VZ]) * 100 ), int( (hedge->origin().x - vOrigin[VX]) * 100 )); - } while((hedge = &hedge->next()) != face.hedge()); + } while((hedge = &hedge->next()) != poly.hedge()); // Check each of the ranges defined by the edges. - for(int i = 0; i < face.hedgeCount() - 1; ++i) + for(int i = 0; i < poly.hedgeCount() - 1; ++i) { // The last edge won't be checked. This is because the edges // define a closed, convex polygon and the last edge's range is diff --git a/doomsday/client/src/render/rend_fakeradio.cpp b/doomsday/client/src/render/rend_fakeradio.cpp index e8401e830a..81d5bcf5b0 100644 --- a/doomsday/client/src/render/rend_fakeradio.cpp +++ b/doomsday/client/src/render/rend_fakeradio.cpp @@ -1346,7 +1346,10 @@ void Rend_RadioBspLeafEdges(BspLeaf &bspLeaf) for(int pln = 0; pln < sector.planeCount(); ++pln) { - writeShadowSection(pln, *side, shadowDark); + if(doPlanes[pln]) + { + writeShadowSection(pln, *side, shadowDark); + } } // Mark it rendered for this frame. diff --git a/doomsday/client/src/render/rend_main.cpp b/doomsday/client/src/render/rend_main.cpp index 19116abece..8075c2453b 100644 --- a/doomsday/client/src/render/rend_main.cpp +++ b/doomsday/client/src/render/rend_main.cpp @@ -2236,7 +2236,7 @@ static void occludeLeaf(bool frontFacing) continue; BspLeaf *backLeaf = hedge->twin().face().mapElement()->as(); - if(backLeaf->isDegenerate() || !backLeaf->hasSector()) + if(!backLeaf->hasSector()) continue; Sector const &frontSec = leaf->sector(); @@ -2330,7 +2330,7 @@ static void drawCurrentLeaf() */ occludeLeaf(false /* back facing */); - LO_ClipInBspLeaf(leaf->indexInMap()); + LO_ClipInBspLeaf(*leaf); occludeLeaf(true /* front facing */); clipLeafFrontFacingWalls(); @@ -2338,7 +2338,7 @@ static void drawCurrentLeaf() if(leaf->polyobjCount()) { // Polyobjs don't obstruct - clip lights with another algorithm. - LO_ClipInBspLeafBySight(leaf->indexInMap()); + LO_ClipInBspLeafBySight(*leaf); } // Mark particle generators in the sector visible. @@ -2415,7 +2415,7 @@ static void traverseBspAndDrawLeafs(MapElement *bspElement) return; // Is this leaf visible? - if(!firstBspLeaf && !C_CheckBspLeaf(*bspLeaf)) + if(!firstBspLeaf && !C_IsPolyVisible(bspLeaf->poly())) return; // This is now the current leaf. diff --git a/doomsday/client/src/world/bspleaf.cpp b/doomsday/client/src/world/bspleaf.cpp index 8d3a4f36ac..6a83ed2bb1 100644 --- a/doomsday/client/src/world/bspleaf.cpp +++ b/doomsday/client/src/world/bspleaf.cpp @@ -659,6 +659,7 @@ void BspLeaf::clearShadowLines() void BspLeaf::addShadowLine(Line::Side &side) { + if(isDegenerate()) return; d->shadowLines.insert(&side); } diff --git a/doomsday/client/src/world/p_mobj.cpp b/doomsday/client/src/world/p_mobj.cpp index 0a1b4d1117..bb07d27077 100644 --- a/doomsday/client/src/world/p_mobj.cpp +++ b/doomsday/client/src/world/p_mobj.cpp @@ -350,7 +350,7 @@ D_CMD(InspectMobj) mo->origin[0], mo->origin[1], mo->origin[2], mo->mom[0], mo->mom[1], mo->mom[2]); Con_Printf("FloorZ:%f CeilingZ:%f\n", mo->floorZ, mo->ceilingZ); - if(mo->bspLeaf) + if(mo->bspLeaf && mo->bspLeaf->hasSector()) { Sector §or = mo->bspLeaf->sector(); Con_Printf("Sector:%i (FloorZ:%f CeilingZ:%f)\n", P_ToIndex(§or), diff --git a/doomsday/client/src/world/p_objlink.cpp b/doomsday/client/src/world/p_objlink.cpp index 8844b224b5..deb9d9c2d6 100644 --- a/doomsday/client/src/world/p_objlink.cpp +++ b/doomsday/client/src/world/p_objlink.cpp @@ -361,18 +361,12 @@ static void maybeSpreadOverEdge(HEdge *hedge, contactfinderparams_t *parms) BspLeaf *leaf = hedge->face().mapElement()->as(); - DENG_ASSERT(!leaf->isDegenerate()); - // There must be a back BSP leaf to spread to. if(!hedge->hasTwin() || !hedge->twin().hasFace()) return; DENG_ASSERT(hedge->twin().face().mapElement() != 0); - BspLeaf *backLeaf = hedge->twin().face().mapElement()->as(); - // Never spread to degenerate BspLeafs. - if(backLeaf->isDegenerate()) return; - // Which way does the spread go? if(!(leaf->validCount() == validCount && backLeaf->validCount() != validCount)) { @@ -550,8 +544,6 @@ static void findContacts(objlink_t *link) static void spreadContactsForBspLeaf(objlinkblockmap_t &obm, BspLeaf const &bspLeaf, float maxRadius) { - DENG_ASSERT(!bspLeaf.isDegenerate()); - AABoxd const &leafAABox = bspLeaf.poly().aaBox(); uint minBlock[2]; @@ -591,7 +583,7 @@ static inline float maxRadius(objtype_t type) void R_InitForBspLeaf(BspLeaf &bspLeaf) { - if(bspLeaf.isDegenerate()) return; + DENG_ASSERT(!bspLeaf.isDegenerate()); BEGIN_PROF( PROF_OBJLINK_SPREAD ); diff --git a/doomsday/client/src/world/p_players.cpp b/doomsday/client/src/world/p_players.cpp index 43bf1d5206..e45d5c7255 100644 --- a/doomsday/client/src/world/p_players.cpp +++ b/doomsday/client/src/world/p_players.cpp @@ -122,7 +122,10 @@ boolean P_IsInVoid(player_t *player) { if(ddpl->inVoid) return true; - if(ddpl->mo && ddpl->mo->bspLeaf) + if(!ddpl->mo->bspLeaf || !ddpl->mo->bspLeaf->hasSector()) + return true; + + if(ddpl->mo) { Sector &sec = ddpl->mo->bspLeaf->sector(); diff --git a/doomsday/client/src/world/world.cpp b/doomsday/client/src/world/world.cpp index b6d4e8e86a..0ec55dd8bf 100644 --- a/doomsday/client/src/world/world.cpp +++ b/doomsday/client/src/world/world.cpp @@ -589,17 +589,18 @@ DENG2_PIMPL(World) if(mobj_t *mo = ddpl.mo) { - Sector §or = map->bspLeafAt(mo->origin).sector(); - + if(Sector *sector = map->bspLeafAt(mo->origin).sectorPtr()) + { #ifdef __CLIENT__ - if(mo->origin[VZ] >= sector.floor().visHeight() && - mo->origin[VZ] < sector.ceiling().visHeight() - 4) + if(mo->origin[VZ] >= sector->floor().visHeight() && + mo->origin[VZ] < sector->ceiling().visHeight() - 4) #else - if(mo->origin[VZ] >= sector.floor().height() && - mo->origin[VZ] < sector.ceiling().height() - 4) + if(mo->origin[VZ] >= sector->floor().height() && + mo->origin[VZ] < sector->ceiling().height() - 4) #endif - { - ddpl.inVoid = false; + { + ddpl.inVoid = false; + } } } }