Skip to content

Commit

Permalink
SectionEdge: Encapsulate more geometry generation logic
Browse files Browse the repository at this point in the history
  • Loading branch information
danij-deng committed May 2, 2013
1 parent 0f68008 commit cca378d
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 70 deletions.
23 changes: 13 additions & 10 deletions doomsday/client/include/map/hedge.h
Expand Up @@ -44,33 +44,35 @@ class Sector;
class SectionEdge
{
public:
/// Invalid range geometry was specified to prepare() @ingroup errors
/// Invalid range geometry was found during prepare() @ingroup errors
DENG2_ERROR(InvalidError);

public:
SectionEdge(HEdge &hedge, int edge, int section);

void prepare(coord_t bottom, coord_t top);
void prepare();

bool isValid() const;

int divisionCount() const;
de::Vector2d const &origin() const;

de::WallDivs::Intercept &firstDivision() const;
coord_t lineOffset() const;

de::WallDivs::Intercept &lastDivision() const;
Line::Side &lineSide() const;

int section() const;

int divisionCount() const;

de::WallDivs::Intercept &bottom() const;

de::WallDivs::Intercept &top() const;

HEdge &hedge() const;

int section() const;
de::WallDivs::Intercept &firstDivision() const;

de::Vector2d const &origin() const;
de::WallDivs::Intercept &lastDivision() const;

coord_t offset() const;
de::Vector2f const &materialOrigin() const;

private:
void verifyValid() const;
Expand All @@ -86,6 +88,7 @@ class SectionEdge
int _section;

bool _isValid;
de::Vector2f _materialOrigin;
int _interceptCount;
de::WallDivs::Intercept *_firstIntercept;
de::WallDivs::Intercept *_lastIntercept;
Expand Down
65 changes: 40 additions & 25 deletions doomsday/client/src/map/hedge.cpp
Expand Up @@ -363,11 +363,6 @@ SectionEdge::SectionEdge(HEdge &hedge, int edge, int section)
DENG_ASSERT(_hedge->hasLineSide() && _hedge->lineSide().hasSections());
}

bool SectionEdge::isValid() const
{
return _isValid;
}

void SectionEdge::verifyValid() const
{
if(!isValid())
Expand All @@ -377,21 +372,34 @@ void SectionEdge::verifyValid() const
}
}

int SectionEdge::divisionCount() const
bool SectionEdge::isValid() const
{
return isValid()? _interceptCount - 2 : 0;
return _isValid;
}

WallDivs::Intercept &SectionEdge::firstDivision() const
Line::Side &SectionEdge::lineSide() const
{
verifyValid();
return _firstIntercept->next();
return _hedge->lineSide();
}

WallDivs::Intercept &SectionEdge::lastDivision() const
int SectionEdge::section() const
{
verifyValid();
return _lastIntercept->prev();
return _section;
}

Vector2d const &SectionEdge::origin() const
{
return _hedge->vertex(_edge).origin();
}

coord_t SectionEdge::lineOffset() const
{
return _hedge->lineOffset() + (_edge? _hedge->length() : 0);
}

int SectionEdge::divisionCount() const
{
return isValid()? _interceptCount - 2 : 0;
}

WallDivs::Intercept &SectionEdge::bottom() const
Expand All @@ -406,24 +414,22 @@ WallDivs::Intercept &SectionEdge::top() const
return *_lastIntercept;
}

HEdge &SectionEdge::hedge() const
{
return *_hedge;
}

int SectionEdge::section() const
WallDivs::Intercept &SectionEdge::firstDivision() const
{
return _section;
verifyValid();
return _firstIntercept->next();
}

Vector2d const &SectionEdge::origin() const
WallDivs::Intercept &SectionEdge::lastDivision() const
{
return _hedge->vertex(_edge).origin();
verifyValid();
return _lastIntercept->prev();
}

coord_t SectionEdge::offset() const
Vector2f const &SectionEdge::materialOrigin() const
{
return _hedge->lineOffset() + (_edge? _hedge->length() : 0);
verifyValid();
return _materialOrigin;
}

void SectionEdge::addPlaneIntercepts(coord_t bottom, coord_t top)
Expand Down Expand Up @@ -559,13 +565,22 @@ void SectionEdge::assertDivisionsInRange(coord_t low, coord_t hi) const
#endif
}

void SectionEdge::prepare(coord_t bottom, coord_t top)
void SectionEdge::prepare()
{
DENG_ASSERT(wallDivs.isEmpty());

Sector *frontSec, *backSec;
_hedge->wallSectionSectors(&frontSec, &backSec);

coord_t bottom, top;
R_SideSectionCoords(_hedge->lineSide(), _section, frontSec, backSec,
&bottom, &top, &_materialOrigin);

_isValid = (top >= bottom);
if(!_isValid) return;

_materialOrigin.x += float(_hedge->lineOffset());

// Intercepts are arranged in ascending distance order.

// The first intercept is the bottom.
Expand Down
49 changes: 14 additions & 35 deletions doomsday/client/src/render/rend_main.cpp
Expand Up @@ -1577,7 +1577,7 @@ static bool writeWallSection(SectionEdge const &leftEdge, SectionEdge const &rig
BspLeaf *bspLeaf = currentBspLeaf;
DENG_ASSERT(!isNullLeaf(bspLeaf));

Line::Side &side = leftEdge.hedge().lineSide();
Line::Side &side = leftEdge.lineSide();
Surface &surface = side.surface(leftEdge.section());

// Surfaces without a drawable material are never rendered.
Expand Down Expand Up @@ -1692,7 +1692,7 @@ static bool writeWallSection(SectionEdge const &leftEdge, SectionEdge const &rig
// Linearly interpolate to find the light level delta values for the
// vertical edges of this wall section.
coord_t const lineLength = side.line().length();
coord_t const sectionOffset = leftEdge.offset();
coord_t const sectionOffset = leftEdge.lineOffset();

float deltaDiff = deltaR - deltaL;
deltaR = deltaL + ((sectionOffset + width) / lineLength) * deltaDiff;
Expand Down Expand Up @@ -1834,10 +1834,10 @@ static bool writeWallSection(SectionEdge const &leftEdge, SectionEdge const &rig
radioParms.sideCn = frData.sideCorners;
radioParms.spans = frData.spans;

radioParms.segOffset = leftEdge.offset();
radioParms.segOffset = leftEdge.lineOffset();
radioParms.segLength = width;

leftEdge.hedge().wallSectionSectors(&radioParms.frontSec);
mapElement.castTo<HEdge>()->wallSectionSectors(&radioParms.frontSec);

radioParms.leftEdge = parm.wall.leftEdge;
radioParms.rightEdge = parm.wall.rightEdge;
Expand Down Expand Up @@ -2441,30 +2441,6 @@ static void writeLeafSkyMask(int skyCap = SKYCAP_LOWER|SKYCAP_UPPER)
}
}

/**
* Prepare wall section edge data for a map line segment.
*
* Return values:
* @param leftEdge Edge data for the left of the wall section is written here.
* @param rightEdge Edge data for the right of the wall section is written here.
* @param materialOrigin Material origin offset data is written here.
*/
static void prepareWallSectionEdges(SectionEdge &leftEdge, SectionEdge &rightEdge,
Vector2f &materialOrigin)
{
Sector *frontSec, *backSec;
leftEdge.hedge().wallSectionSectors(&frontSec, &backSec);

coord_t bottom, top;
R_SideSectionCoords(leftEdge.hedge().lineSide(), leftEdge.section(), frontSec, backSec,
&bottom, &top, &materialOrigin);

leftEdge.prepare(bottom, top);
rightEdge.prepare(bottom, top);

materialOrigin.x += float(leftEdge.offset());
}

/**
* Prepare edges and write the specified wall @a section to the render lists.
*
Expand Down Expand Up @@ -2494,15 +2470,15 @@ static bool prepareEdgesAndWriteWallSection(HEdge &hedge, int section, bool *opa

SectionEdge leftEdge(hedge, HEdge::From, section);
SectionEdge rightEdge(hedge, HEdge::To, section);
Vector2f materialOrigin;

prepareWallSectionEdges(leftEdge, rightEdge, materialOrigin);
leftEdge.prepare();
rightEdge.prepare();

if(leftEdge.isValid() && rightEdge.isValid() &&
rightEdge.top().distance() > leftEdge.bottom().distance())
{
bool wroteOpaquePoly =
writeWallSection(leftEdge, rightEdge, materialOrigin,
writeWallSection(leftEdge, rightEdge, leftEdge.materialOrigin(),
hedge, hedge.biasSurfaceForGeometryGroup(section));

if(opaque) *opaque = wroteOpaquePoly;
Expand Down Expand Up @@ -2608,14 +2584,17 @@ static void writeWallSections(HEdge &hedge)

SectionEdge leftEdge(hedge, HEdge::From, Line::Side::Middle);
SectionEdge rightEdge(hedge, HEdge::To, Line::Side::Middle);
Vector2f materialOrigin;

prepareWallSectionEdges(leftEdge, rightEdge, materialOrigin);
leftEdge.prepare();
rightEdge.prepare();

if(leftEdge.isValid() && rightEdge.isValid() &&
rightEdge.top().distance() > leftEdge.bottom().distance())
{
wroteOpaqueMiddle = writeWallSection(leftEdge, rightEdge, materialOrigin,
hedge, hedge.biasSurfaceForGeometryGroup(Line::Side::Middle));
wroteOpaqueMiddle =
writeWallSection(leftEdge, rightEdge, leftEdge.materialOrigin(),
hedge, hedge.biasSurfaceForGeometryGroup(Line::Side::Middle));

if(wroteOpaqueMiddle)
{
// Did we completely cover the open range?
Expand Down

0 comments on commit cca378d

Please sign in to comment.