Skip to content

Commit

Permalink
Sector: Enumerate referencing map line sides instead of lines
Browse files Browse the repository at this point in the history
Maintaining a list of map lines which reference the sector is useful.
However, more useful is a list of the referencing map line sides, as
this then simplifies the logic for any users of this list (there is
no need to then deduce which side(s) of the line has the reference).
  • Loading branch information
danij-deng committed May 9, 2013
1 parent 6cd8fef commit c495c97
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 75 deletions.
23 changes: 13 additions & 10 deletions doomsday/client/include/map/sector.h
Expand Up @@ -30,11 +30,11 @@
#include <de/Vector>

#include "MapElement"
#include "Line"
#include "Plane"

class BspLeaf;
class GameMap;
class Line;
class Surface;

/**
Expand Down Expand Up @@ -71,7 +71,7 @@ class Sector : public de::MapElement,
static float const DEFAULT_LIGHT_LEVEL; ///< 1.f
static de::Vector3f const DEFAULT_LIGHT_COLOR; ///< red=1.f green=1.f, blue=1.f

typedef QList<Line *> Lines;
typedef QList<Line::Side *> Sides;
typedef QList<Plane *> Planes;
typedef QList<BspLeaf *> BspLeafs;

Expand Down Expand Up @@ -196,28 +196,31 @@ class Sector : public de::MapElement,
inline Surface const &ceilingSurface() const { return ceiling().surface(); }

/**
* Provides access to the list of lines which reference the sector,
* Provides access to the list of line sides which reference the sector,
* for efficient traversal.
*/
Lines const &lines() const;
Sides const &sides() const;

/**
* Returns the total number of lines which reference the sector.
* Returns the total number of line sides which reference the sector.
*/
inline uint lineCount() const { return uint(lines().count()); }
inline uint sideCount() const { return uint(sides().count()); }

/**
* (Re)Build the line list for the sector.
* (Re)Build the side list for the sector.
*
* @note In the special case of self-referencing line, only the front side
* reference is added to this list.
*
* @attention The behavior of some algorithms used in the DOOM game logic
* is dependant upon the order of this list. For example, EV_DoFloor and
* EV_BuildStairs. That same order is used here, for compatibility.
*
* Order: Original line index, ascending.
* Order: Original @em line index, ascending.
*
* @param map Map to collate lines from. @todo Refactor away.
* @param map Map to collate sides from. @todo Refactor away.
*/
void buildLines(GameMap const &map);
void buildSides(GameMap const &map);

/**
* Provides access to the list of BSP leafs which reference the sector, for
Expand Down
4 changes: 2 additions & 2 deletions doomsday/client/src/audio/s_environ.cpp
Expand Up @@ -147,7 +147,7 @@ static void setBspLeafSectorOwner(ownerlist_t *ownerList, BspLeaf *bspLeaf)

static void findBspLeafsAffectingSector(GameMap *map, Sector *sec)
{
if(!sec || !sec->lineCount()) return;
if(!sec || !sec->sideCount()) return;

ownerlist_t bspLeafOwnerList;
std::memset(&bspLeafOwnerList, 0, sizeof(bspLeafOwnerList));
Expand Down Expand Up @@ -314,7 +314,7 @@ static boolean calcBspLeafReverb(BspLeaf *bspLeaf)

static void calculateSectorReverb(Sector *sec)
{
if(!sec || !sec->lineCount()) return;
if(!sec || !sec->sideCount()) return;

uint spaceVolume = int((sec->ceiling().height() - sec->floor().height()) * sec->roughArea());

Expand Down
57 changes: 27 additions & 30 deletions doomsday/client/src/map/gamemap.cpp
Expand Up @@ -171,7 +171,7 @@ DENG2_PIMPL(GameMap)
foreach(Sector *sector, self._sectors)
{
sector->buildBspLeafs(self);
sector->buildLines(self);
sector->buildSides(self);
sector->updateAABox();
sector->updateRoughArea();

Expand All @@ -193,21 +193,20 @@ DENG2_PIMPL(GameMap)
}

// Link wall surface emitters:
foreach(Line *line, sector->lines())
foreach(Line::Side *side, sector->sides())
{
if(line->frontSectorPtr() == sector)
if(side->hasSections())
{
Line::Side &side = line->front();
sector->linkSoundEmitter(side.middleSoundEmitter());
sector->linkSoundEmitter(side.bottomSoundEmitter());
sector->linkSoundEmitter(side.topSoundEmitter());
sector->linkSoundEmitter(side->middleSoundEmitter());
sector->linkSoundEmitter(side->bottomSoundEmitter());
sector->linkSoundEmitter(side->topSoundEmitter());
}
if(line->hasBackSections() && line->backSectorPtr() == sector)
if(side->line().isSelfReferencing() && side->back().hasSections())
{
Line::Side &side = line->back();
sector->linkSoundEmitter(side.middleSoundEmitter());
sector->linkSoundEmitter(side.bottomSoundEmitter());
sector->linkSoundEmitter(side.topSoundEmitter());
Line::Side &back = side->back();
sector->linkSoundEmitter(back.middleSoundEmitter());
sector->linkSoundEmitter(back.bottomSoundEmitter());
sector->linkSoundEmitter(back.topSoundEmitter());
}
}

Expand Down Expand Up @@ -288,7 +287,7 @@ DENG2_PIMPL(GameMap)

void updateMapSkyFixForSector(Sector const &sector)
{
if(!sector.lineCount()) return;
if(!sector.sideCount()) return;

bool const skyFloor = sector.floorSurface().hasSkyMaskedMaterial();
bool const skyCeil = sector.ceilingSurface().hasSkyMaskedMaterial();
Expand Down Expand Up @@ -329,14 +328,12 @@ DENG2_PIMPL(GameMap)

// Update for middle textures on two sided lines which intersect the
// floor and/or ceiling of their front and/or back sectors.
foreach(Line *line, sector.lines())
foreach(Line::Side *side, sector.sides())
{
Line::Side &side = line->frontSectorPtr() == &sector? line->front() : line->back();
if(!side->hasSections()) continue;
if(!side->middle().hasMaterial()) continue;

if(!side.hasSections()) continue;
if(!side.middle().hasMaterial()) continue;

HEdge const *hedge = side.leftHEdge();
HEdge const *hedge = side->leftHEdge();
Sector const *frontSec = hedge->wallSectionSector(HEdge::Front);
Sector const *backSec = hedge->wallSectionSector(HEdge::Back);

Expand All @@ -345,7 +342,7 @@ DENG2_PIMPL(GameMap)

coord_t bottomZ, topZ;
Vector2f materialOrigin;
R_SideSectionCoords(side, Line::Side::Middle, frontSec, backSec,
R_SideSectionCoords(*side, Line::Side::Middle, frontSec, backSec,
&bottomZ, &topZ, &materialOrigin);
if(skyCeil && topZ + materialOrigin.y > self.skyFixCeiling())
{
Expand Down Expand Up @@ -673,7 +670,7 @@ void GameMap::buildSurfaceLists()
foreach(Sector *sector, _sectors)
{
// Skip sectors with no lines as their planes will never be drawn.
if(!sector->lineCount()) continue;
if(!sector->sideCount()) continue;

foreach(Plane *plane, sector->planes())
{
Expand Down Expand Up @@ -1973,29 +1970,29 @@ static void addMissingMaterial(Line::Side &side, int section)

void GameMap::updateMissingMaterialsForLinesOfSector(Sector const &sec)
{
foreach(Line *line, sec.lines())
foreach(Line::Side *side, sec.sides())
{
/**
* Do as in the original Doom if the texture has not been defined -
* extend the floor/ceiling to fill the space (unless it is skymasked),
* or if there is a midtexture use that instead.
*/
if(line->hasBackSector())
if(side->hasSector() && side->back().hasSector())
{
Sector const &frontSec = line->frontSector();
Sector const &backSec = line->backSector();
Sector const &frontSec = side->sector();
Sector const &backSec = side->back().sector();

// A potential bottom section fix?
if(!(frontSec.floorSurface().hasSkyMaskedMaterial() &&
backSec.floorSurface().hasSkyMaskedMaterial()))
{
if(frontSec.floor().height() < backSec.floor().height())
{
addMissingMaterial(line->front(), Line::Side::Bottom);
addMissingMaterial(*side, Line::Side::Bottom);
}
else if(frontSec.floor().height() > backSec.floor().height())
{
addMissingMaterial(line->back(), Line::Side::Bottom);
addMissingMaterial(side->back(), Line::Side::Bottom);
}
}

Expand All @@ -2005,18 +2002,18 @@ void GameMap::updateMissingMaterialsForLinesOfSector(Sector const &sec)
{
if(backSec.ceiling().height() < frontSec.ceiling().height())
{
addMissingMaterial(line->front(), Line::Side::Top);
addMissingMaterial(*side, Line::Side::Top);
}
else if(backSec.ceiling().height() > frontSec.ceiling().height())
{
addMissingMaterial(line->back(), Line::Side::Top);
addMissingMaterial(side->back(), Line::Side::Top);
}
}
}
else
{
// A potential middle section fix.
addMissingMaterial(line->front(), Line::Side::Middle);
addMissingMaterial(*side, Line::Side::Middle);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions doomsday/client/src/map/p_dmu.cpp
Expand Up @@ -402,9 +402,9 @@ int P_Iteratep(void *elPtr, uint prop, void *context, int (*callback) (void *p,
switch(prop)
{
case DMU_LINE:
foreach(Line *line, elem->castTo<Sector>()->lines())
foreach(Line::Side *side, elem->castTo<Sector>()->sides())
{
int result = callback(line, context);
int result = callback(&side->line(), context);
if(result) return result;
}
return false; // Continue iteration
Expand Down
4 changes: 2 additions & 2 deletions doomsday/client/src/map/p_maputil.cpp
Expand Up @@ -482,9 +482,9 @@ int GameMap_SectorTouchingMobjsIterator(GameMap *map, Sector *sector,

// Collate mobjs linked to the sector's lines.
linknode_t const *ln = map->lineNodes.nodes;
foreach(Line *line, sector->lines())
foreach(Line::Side *side, sector->sides())
{
nodeindex_t root = map->lineLinks[line->indexInMap()];
nodeindex_t root = map->lineLinks[side->line().indexInMap()];

for(nodeindex_t nix = ln[root].next; nix != root; nix = ln[nix].next)
{
Expand Down
4 changes: 2 additions & 2 deletions doomsday/client/src/map/p_particle.cpp
Expand Up @@ -179,7 +179,7 @@ void P_MapSpawnPlaneParticleGens()
foreach(Sector *sector, theMap->sectors())
{
// Only planes of sectors with volume on the world X/Y axis support generators.
if(!sector->lineCount()) continue;
if(!sector->sideCount()) continue;

for(uint i = 0; i < 2; ++i)
{
Expand Down Expand Up @@ -361,7 +361,7 @@ void P_SpawnPlaneParticleGen(ded_ptcgen_t const *def, Plane *plane)
if(isDedicated || !useParticles) return;
if(!def || !plane) return;
// Only planes in sectors with volume on the world X/Y axis can support generators.
if(!plane->sector().lineCount()) return;
if(!plane->sector().sideCount()) return;

// Plane we spawn relative to may not be this one.
Plane::Type relPlane = plane->type();
Expand Down
15 changes: 7 additions & 8 deletions doomsday/client/src/map/plane.cpp
Expand Up @@ -172,19 +172,18 @@ DENG2_PIMPL(Plane)

// Mark the decor lights on the sides of this plane as requiring
// an update.
foreach(Line *line, sector->lines())
foreach(Line::Side *side, sector->sides())
{
if(line->hasFrontSections())
if(side->hasSections())
{
Line::Side &front = line->front();
front.middle().markAsNeedingDecorationUpdate();
front.bottom().markAsNeedingDecorationUpdate();
front.top().markAsNeedingDecorationUpdate();
side->middle().markAsNeedingDecorationUpdate();
side->bottom().markAsNeedingDecorationUpdate();
side->top().markAsNeedingDecorationUpdate();
}

if(line->hasBackSections())
if(side->back().hasSections())
{
Line::Side &back = line->back();
Line::Side &back = side->back();
back.middle().markAsNeedingDecorationUpdate();
back.bottom().markAsNeedingDecorationUpdate();
back.top().markAsNeedingDecorationUpdate();
Expand Down
36 changes: 20 additions & 16 deletions doomsday/client/src/map/sector.cpp
Expand Up @@ -54,8 +54,8 @@ DENG2_PIMPL(Sector)
/// List of planes (owned).
Planes planes;

/// List of lines which reference the sector (not owned).
Lines lines;
/// List of line sides which reference the sector (not owned).
Sides sides;

/// List of BSP leafs which reference the sector (not owned).
BspLeafs bspLeafs;
Expand Down Expand Up @@ -229,36 +229,40 @@ Plane const &Sector::plane(int planeIndex) const
return const_cast<Plane const &>(const_cast<Sector &>(*this).plane(planeIndex));
}

Sector::Lines const &Sector::lines() const
Sector::Sides const &Sector::sides() const
{
return d->lines;
return d->sides;
}

void Sector::buildLines(GameMap const &map)
void Sector::buildSides(GameMap const &map)
{
d->lines.clear();
d->sides.clear();

#ifdef DENG2_QT_4_7_OR_NEWER
uint count = 0;
foreach(Line *line, map.lines())
{
if(line->frontSectorPtr() == this ||
line->backSectorPtr() == this)
if(line->front().sectorPtr() == this ||
line->back().sectorPtr() == this)
++count;
}

if(0 == count) return;

d->lines.reserve(count);
d->sides.reserve(count);
#endif

foreach(Line *line, map.lines())
{
if(line->frontSectorPtr() == this ||
line->backSectorPtr() == this)
if(line->front().sectorPtr() == this)
{
// Ownership of the line is not given to the sector.
d->lines.append(line);
// Ownership of the side is not given to the sector.
d->sides.append(&line->front());
}
else if(line->back().sectorPtr() == this)
{
// Ownership of the side is not given to the sector.
d->sides.append(&line->back());
}
}
}
Expand Down Expand Up @@ -424,10 +428,10 @@ void Sector::planeHeightChanged(Plane &plane, coord_t oldHeight)
}

// Update the sound emitter origins for all dependent wall surfaces.
foreach(Line *line, d->lines)
foreach(Line::Side *side, d->sides)
{
line->front().updateAllSoundEmitterOrigins();
line->back().updateAllSoundEmitterOrigins();
side->updateAllSoundEmitterOrigins();
side->back().updateAllSoundEmitterOrigins();
}

#ifdef __CLIENT__
Expand Down
2 changes: 1 addition & 1 deletion doomsday/client/src/render/r_lgrid.cpp
Expand Up @@ -457,7 +457,7 @@ void LG_InitForMap(void)
{
count = changedCount = 0;

if(sector->lineCount())
if(sector->sideCount())
{
// Clear the bitfields.
std::memset(indexBitfield, 0, bitfieldSize);
Expand Down
4 changes: 2 additions & 2 deletions doomsday/client/src/render/r_main.cpp
Expand Up @@ -1399,8 +1399,8 @@ void Rend_CacheForMap()

foreach(Sector *sector, theMap->sectors())
{
// Skip sectors with no lines as their planes will never be drawn.
if(!sector->lineCount()) continue;
// Skip sectors with no line sides as their planes will never be drawn.
if(!sector->sideCount()) continue;

foreach(Plane *plane, sector->planes())
{
Expand Down

0 comments on commit c495c97

Please sign in to comment.