Skip to content

Commit

Permalink
WallEdge: Implement the IEdge interface/model
Browse files Browse the repository at this point in the history
WallEdges can now used with TriangleStripBuilder.
  • Loading branch information
danij-deng committed May 24, 2013
1 parent 427a020 commit 2ef1b6a
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 33 deletions.
37 changes: 24 additions & 13 deletions doomsday/client/include/render/walledge.h
Expand Up @@ -28,6 +28,7 @@
#include "Line"
#include "WallSpec"

#include "TriangleStripBuilder"
#include "IHPlane"

class HEdge;
Expand All @@ -44,7 +45,7 @@ namespace de {
*
* @ingroup map
*/
class WallEdge
class WallEdge : public IEdge
{
DENG2_NO_COPY (WallEdge)
DENG2_NO_ASSIGN(WallEdge)
Expand All @@ -53,20 +54,23 @@ class WallEdge
/// Invalid range geometry was found during prepare() @ingroup errors
DENG2_ERROR(InvalidError);

class Intercept : public de::IHPlane::IIntercept
class Intercept : public IEdge::IIntercept,
public IHPlane::IIntercept
{
public:
Intercept(WallEdge *owner, double distance = 0);
Intercept(WallEdge &owner, double distance = 0);

WallEdge &owner() const;
bool operator < (Intercept const &other) const;

de::Vector3d origin() const;
double distance() const;

Vector3d origin() const;

private:
WallEdge *_owner;
DENG2_PRIVATE(d)
};

typedef QList<Intercept> Intercepts;
typedef QList<Intercept *> Intercepts;

public:
/**
Expand All @@ -80,9 +84,19 @@ class WallEdge

WallSpec const &spec() const;

/// Implements IEdge.
bool isValid() const;

de::Vector2d const &origin() const;
/// Implements IEdge.
Intercept const &from() const;

/// Implements IEdge.
Intercept const &to() const;

/// Implements IEdge.
Vector2f const &materialOrigin() const;

Vector2d const &origin() const;

coord_t mapLineOffset() const;

Expand All @@ -94,16 +108,13 @@ class WallEdge

int divisionCount() const;

Intercept const &bottom() const;

Intercept const &top() const;
inline Intercept const &bottom() const { return from(); }
inline Intercept const &top() const { return to(); }

int firstDivision() const;

int lastDivision() const;

de::Vector2f const &materialOrigin() const;

de::Vector3f const &normal() const;

Intercepts const &intercepts() const;
Expand Down
61 changes: 41 additions & 20 deletions doomsday/client/src/render/walledge.cpp
Expand Up @@ -45,19 +45,32 @@ static bool shouldSmoothNormals(Surface &sufA, Surface &sufB, binangle_t angleDi
return INRANGE_OF(angleDiff, BANG_180, BANG_45);
}

WallEdge::Intercept::Intercept(WallEdge *owner, double distance)
DENG2_PIMPL_NOREF(WallEdge::Intercept)
{
/// Wall edge instance which owns "this" intercept.
WallEdge &owner;

Instance(WallEdge &owner) : owner(owner) {}
};

WallEdge::Intercept::Intercept(WallEdge &owner, double distance)
: IHPlane::IIntercept(distance),
_owner(owner)
d(new Instance(owner))
{}

WallEdge &WallEdge::Intercept::owner() const
bool WallEdge::Intercept::operator < (Intercept const &other) const
{
return distance() < other.distance();
}

double WallEdge::Intercept::distance() const
{
return *_owner;
return IHPlane::IIntercept::distance();
}

Vector3d WallEdge::Intercept::origin() const
{
return Vector3d(_owner->origin(), distance());
return Vector3d(d->owner.origin(), distance());
}

DENG2_PIMPL(WallEdge), public IHPlane
Expand Down Expand Up @@ -92,6 +105,14 @@ DENG2_PIMPL(WallEdge), public IHPlane
intercepts (other.intercepts),
needSortIntercepts(other.needSortIntercepts)
{}

~HPlane() { clearIntercepts(); }

void clearIntercepts()
{
qDeleteAll(intercepts);
}

} hplane;

Instance(Public *i, WallSpec const &spec, Line::Side *mapSide, int edge,
Expand Down Expand Up @@ -131,9 +152,9 @@ DENG2_PIMPL(WallEdge), public IHPlane
{
for(int i = 0; i < hplane.intercepts.count(); ++i)
{
WallEdge::Intercept &icpt = hplane.intercepts[i];
if(de::fequal(icpt.distance(), distance))
return &icpt;
WallEdge::Intercept *icpt = hplane.intercepts[i];
if(de::fequal(icpt->distance(), distance))
return icpt;
}
return 0;
}
Expand All @@ -144,8 +165,8 @@ DENG2_PIMPL(WallEdge), public IHPlane
if(find(distance))
return 0;

hplane.intercepts.append(WallEdge::Intercept(&self, distance));
WallEdge::Intercept *newIntercept = &hplane.intercepts.last();
hplane.intercepts.append(new WallEdge::Intercept(self, distance));
WallEdge::Intercept *newIntercept = hplane.intercepts.last();

// The addition of a new intercept means we'll need to resort.
hplane.needSortIntercepts = true;
Expand Down Expand Up @@ -176,7 +197,7 @@ DENG2_PIMPL(WallEdge), public IHPlane
{
if(index >= 0 && index < interceptCount())
{
return hplane.intercepts[index];
return *hplane.intercepts[index];
}
/// @throw IHPlane::UnknownInterceptError The specified intercept index is not valid.
throw IHPlane::UnknownInterceptError("HPlane2::at", QString("Index '%1' does not map to a known intercept (count: %2)")
Expand All @@ -193,9 +214,9 @@ DENG2_PIMPL(WallEdge), public IHPlane
void printIntercepts() const
{
uint index = 0;
foreach(WallEdge::Intercept const &icpt, hplane.intercepts)
foreach(WallEdge::Intercept const *icpt, hplane.intercepts)
{
LOG_DEBUG(" %u: >%1.2f ") << (index++) << icpt.distance();
LOG_DEBUG(" %u: >%1.2f ") << (index++) << icpt->distance();
}
}
#endif
Expand All @@ -206,9 +227,9 @@ DENG2_PIMPL(WallEdge), public IHPlane
void assertInterceptsInRange(coord_t low, coord_t hi) const
{
#ifdef DENG_DEBUG
foreach(WallEdge::Intercept const &icpt, hplane.intercepts)
foreach(WallEdge::Intercept const *icpt, hplane.intercepts)
{
DENG2_ASSERT(icpt.distance() >= low && icpt.distance() <= hi);
DENG2_ASSERT(icpt->distance() >= low && icpt->distance() <= hi);
}
#else
DENG2_UNUSED2(low, hi);
Expand Down Expand Up @@ -466,16 +487,16 @@ int WallEdge::divisionCount() const
return d->isValid? d->interceptCount() - 2 : 0;
}

WallEdge::Intercept const &WallEdge::bottom() const
WallEdge::Intercept const &WallEdge::from() const
{
d->verifyValid();
return d->hplane.intercepts[0];
return *d->hplane.intercepts[0];
}

WallEdge::Intercept const &WallEdge::top() const
WallEdge::Intercept const &WallEdge::to() const
{
d->verifyValid();
return d->hplane.intercepts[d->interceptCount()-1];
return *d->hplane.intercepts[d->interceptCount()-1];
}

int WallEdge::firstDivision() const
Expand All @@ -493,7 +514,7 @@ int WallEdge::lastDivision() const
WallEdge::Intercept const &WallEdge::at(int index) const
{
d->verifyValid();
return d->hplane.intercepts[index];
return *d->hplane.intercepts[index];
}

WallEdge::Intercepts const &WallEdge::intercepts() const
Expand Down

0 comments on commit 2ef1b6a

Please sign in to comment.