Skip to content

Commit

Permalink
Refactor|World|ConvexSubspace: Various ConvexSubspace API-cleanup ref…
Browse files Browse the repository at this point in the history
…actorings
  • Loading branch information
danij-deng committed Dec 1, 2014
1 parent 99687a4 commit b1e63eb
Show file tree
Hide file tree
Showing 8 changed files with 415 additions and 318 deletions.
237 changes: 121 additions & 116 deletions doomsday/client/include/world/convexsubspace.h
Expand Up @@ -21,12 +21,10 @@
#ifndef DENG_WORLD_CONVEXSUBSPACE_H
#define DENG_WORLD_CONVEXSUBSPACE_H

#include <QSet>
#include <functional>
#include <de/Error>
#include <de/Vector>

#include "Mesh"

#include "MapElement"
#include "Line"
#include "SectorCluster"
Expand All @@ -48,21 +46,12 @@ class ConvexSubspace : public de::MapElement
/// An invalid polygon was specified. @ingroup errors
DENG2_ERROR(InvalidPolyError);

/// Required BspLeaf attribution is missing. @ingroup errors
DENG2_ERROR(MissingBspLeafError);

/// Required sector cluster attribution is missing. @ingroup errors
DENG2_ERROR(MissingClusterError);

/// Linked-element lists/sets:
typedef QSet<de::Mesh *> Meshes;
typedef QSet<polyobj_s *> Polyobjs;

#ifdef __CLIENT__
typedef QSet<Lumobj *> Lumobjs;
typedef QSet<LineSide *> ShadowLines;

// Final audio environment characteristics.
typedef uint AudioEnvironmentFactors[NUM_REVERB_DATA];
#endif

public:
/**
* Attempt to construct a ConvexSubspace from the Face geometry provided.
Expand All @@ -73,18 +62,6 @@ class ConvexSubspace : public de::MapElement
*/
static ConvexSubspace *newFromConvexPoly(de::Face &poly, BspLeaf *bspLeaf = 0);

/**
* Returns the BspLeaf to which the subspace is assigned.
*/
BspLeaf &bspLeaf() const;

void setBspLeaf(BspLeaf *newBspLeaf);

/**
* Provides access to the attributed convex geometry (a polygon).
*/
de::Face &poly() const;

/**
* Determines whether the specified @a point in the map coordinate space
* lies inside the convex polygon geometry of the subspace on the XY plane.
Expand All @@ -97,6 +74,11 @@ class ConvexSubspace : public de::MapElement
*/
bool contains(de::Vector2d const &point) const;

/**
* Provides access to the attributed convex geometry (a polygon).
*/
de::Face &poly() const;

/**
* Assign an additional mesh geometry to the subspace. Such @em extra meshes
* are used to represent geometry which would otherwise result in a
Expand All @@ -108,69 +90,36 @@ class ConvexSubspace : public de::MapElement
void assignExtraMesh(de::Mesh &mesh);

/**
* Provides access to the set of 'extra' mesh geometries for the subspace.
*
* @see assignExtraMesh()
*/
Meshes const &extraMeshes() const;

/**
* Remove the given @a polyobj from the set of those linked to the subspace.
* Iterate through the 'extra' meshes of the subspace.
*
* @return @c true= @a polyobj was linked and subsequently removed.
*/
bool unlink(polyobj_s const &polyobj);

/**
* Add the given @a polyobj to the set of those linked to the subspace.
* Ownership is unaffected. If the polyobj is already linked in this set
* then nothing will happen.
*/
void link(struct polyobj_s const &polyobj);

/**
* Provides access to the set of polyobjs linked to the subspace.
* @param func Callback to make for each Mesh.
*/
Polyobjs const &polyobjs() const;
de::LoopResult forAllExtraMeshes(std::function<de::LoopResult (de::Mesh &)> func) const;

/**
* Convenient method of returning the total number of polyobjs linked to the
* subspace.
* Returns @c true iff a SectorCluster is attributed to the subspace. The
* only time a cluster might not be attributed is during initial map setup.
*/
inline int polyobjCount() { return polyobjs().count(); }
bool hasCluster() const;

/**
* Returns the vector described by the offset from the map coordinate space
* origin to the top most, left most point of the geometry of the subspace.
* Returns the SectorCluster attributed to the subspace.
*
* @see aaBox()
*/
de::Vector2d const &worldGridOffset() const;

/**
* Returns @c true iff a SectorCluster is attributed to the subspace. The
* only time a cluster might not be attributed is during initial map setup.
* @see hasCluster()
*/
bool hasCluster() const;
SectorCluster &cluster() const;
SectorCluster *clusterPtr() const;

/**
* Change the sector cluster attributed to the subspace.
*
* @param newCluster New sector cluster to attribute to the subspace.
* Ownership is unaffected. Can be @c 0 (to clear the
* attribution).
* Ownership is unaffected. Use @c nullptr to clear.
*
* @see hasCluster(), cluster()
*/
void setCluster(SectorCluster *newCluster);

/**
* Returns the SectorCluster attributed to the subspace.
*
* @see hasCluster()
*/
SectorCluster &cluster() const;

/**
* Convenient method returning Sector of the SectorCluster attributed to the
* subspace.
Expand All @@ -180,14 +129,10 @@ class ConvexSubspace : public de::MapElement
inline Sector &sector() const { return cluster().sector(); }

/**
* Convenient method returning a pointer to the SectorCluster attributed to
* the subspace. If not attributed then @c 0 is returned.
*
* @see hasCluster(), cluster()
* Returns the BspLeaf to which the subspace is assigned.
*/
inline SectorCluster *clusterPtr() const {
return hasCluster()? &cluster() : 0;
}
BspLeaf &bspLeaf() const;
void setBspLeaf(BspLeaf *newBspLeaf);

/**
* Returns the @em validCount of the subspace. Used by some legacy iteration
Expand All @@ -202,23 +147,73 @@ class ConvexSubspace : public de::MapElement

#ifdef __CLIENT__
/**
* Clear the list of fake radio shadow line sides for the subspace.
* Returns the vector described by the offset from the map coordinate space
* origin to the top most, left most point of the geometry of the subspace.
*
* @see aaBox()
*/
void clearShadowLines();
de::Vector2d const &worldGridOffset() const;

/**
* Add the specified line @a side to the set of fake radio shadow lines for
* the subspace. If the line is already present in this set then nothing
* will happen.
* Returns a pointer to the face geometry half-edge which has been chosen
* for use as the base for a triangle fan GL primitive. May return @c 0 if
* no suitable base was determined.
*/
de::HEdge *fanBase() const;

/**
* Returns the number of vertices needed for a triangle fan GL primitive.
*
* @param side Map line side to add to the set.
* @note When first called after a face geometry is assigned a new 'base'
* half-edge for the triangle fan primitive will be determined.
*
* @see fanBase()
*/
void addShadowLine(LineSide &side);
int fanVertexCount() const;

/**
* Provides access to the set of fake radio shadow lines for the subspace.
* Returns the frame number of the last time mobj sprite projection was
* performed for the subspace.
*/
ShadowLines const &shadowLines() const;
int lastSpriteProjectFrame() const;
void setLastSpriteProjectFrame(int newFrameNumber);

public: // Audio Environment (reverb) ---------------------------------------------
/**
* Audio environment characteristics.
*/
struct AudioEnvironmentData
{
// Final reverb factors.
typedef uint ReverbFactors[NUM_REVERB_DATA];
ReverbFactors reverb;

AudioEnvironmentData() { de::zap(reverb); }
};

/**
* Recalculate the environmental audio characteristics (reverb) of the subspace.
*/
bool updateAudioEnvironment();

/**
* Provides access to the final environmental audio environment characteristics
* of the subspace, for efficient accumulation.
*/
AudioEnvironmentData const &audioEnvironmentData() const;

public: // Luminous objects -------------------------------------------------------
/**
* Returns the total number of Lumobjs linked to the subspace.
*/
int lumobjCount() const;

/**
* Iterate through the Lumobjs of the subspace.
*
* @param func Callback to make for each Lumobj.
*/
de::LoopResult forAllLumobjs(std::function<de::LoopResult (Lumobj &)> func) const;

/**
* Clear all lumobj links for the subspace.
Expand All @@ -241,65 +236,75 @@ class ConvexSubspace : public de::MapElement
*
* @param lumobj Lumobj to link.
*
* @see lumobjs(), unlink()
* @see unlink()
*/
void link(Lumobj &lumobj);
#endif // __CLIENT__

public: // Poly objects -----------------------------------------------------------
/**
* Provides access to the set of lumobjs linked to the subspace.
*
* @see linkLumobj(), clearLumobjs()
* Returns the total number of Polyobjs linked to the subspace.
*/
Lumobjs const &lumobjs() const;
int polyobjCount() const;

/**
* Returns the frame number of the last time mobj sprite projection was
* performed for the subspace.
* Iterate through the Polyobjs of the subspace.
*
* @param func Callback to make for each Polyobj.
*/
int lastSpriteProjectFrame() const;
de::LoopResult forAllPolyobjs(std::function<de::LoopResult (struct polyobj_s &)> func) const;

/**
* Change the frame number of the last time mobj sprite projection was
* performed for the subspace.
* Remove the given @a polyobj from the set of those linked to the subspace.
*
* @param newFrame New frame number.
* @return @c true= @a polyobj was linked and subsequently removed.
*/
void setLastSpriteProjectFrame(int newFrame);
bool unlink(struct polyobj_s const &polyobj);

/**
* Returns a pointer to the face geometry half-edge which has been chosen
* for use as the base for a triangle fan GL primitive. May return @c 0 if
* no suitable base was determined.
* Add the given @a polyobj to the set of those linked to the subspace.
* Ownership is unaffected. If the polyobj is already linked in this set
* then nothing will happen.
*/
de::HEdge *fanBase() const;
void link(struct polyobj_s const &polyobj);

#ifdef __CLIENT__
public: // Shadowing-lines (fakeradio) --------------------------------------------
/**
* Returns the number of vertices needed for a triangle fan GL primitive.
*
* @note When first called after a face geometry is assigned a new 'base'
* half-edge for the triangle fan primitive will be determined.
*
* @see fanBase()
* Returns the total number of shadow line sides linked in the subspace.
*/
int numFanVertices() const;
int shadowLineCount() const;

/**
* Recalculate the environmental audio characteristics (reverb) of the subspace.
* Clear the list of fake radio shadow line sides for the subspace.
*/
bool updateReverb();
void clearShadowLines();

/**
* Provides access to the final environmental audio characteristics (reverb)
* of the subspace, for efficient accumulation.
* Add the specified line @a side to the set of fake radio shadow lines for
* the subspace. If the line is already present in this set then nothing
* will happen.
*
* @param side Map line side to add to the set.
*/
AudioEnvironmentFactors const &reverb() const;
void addShadowLine(LineSide &side);

/**
* Iterate through the set of fake radio shadow lines for the subspace.
*
* @param func Callback to make for each LineSide.
*/
de::LoopResult forAllShadowLines(std::function<de::LoopResult (LineSide &)> func) const;
#endif // __CLIENT__

private:
ConvexSubspace(de::Face &convexPolygon, BspLeaf *bspLeaf = 0);
ConvexSubspace(de::Face &convexPolygon, BspLeaf *bspLeaf = nullptr);

DENG2_PRIVATE(d)
};

#ifdef __CLIENT__
typedef ConvexSubspace::AudioEnvironmentData ConvexSubspaceAudioEnvironmentData;
#endif

#endif // DENG_WORLD_CONVEXSUBSPACE_H
14 changes: 7 additions & 7 deletions doomsday/client/src/render/rend_fakeradio.cpp
Expand Up @@ -1308,8 +1308,7 @@ void Rend_RadioSubspaceEdges(ConvexSubspace const &subspace)
if(!rendFakeRadio) return;
if(levelFullBright) return;

ConvexSubspace::ShadowLines const &shadowLines = subspace.shadowLines();
if(shadowLines.isEmpty()) return;
if(!subspace.shadowLineCount()) return;

SectorCluster &cluster = subspace.cluster();
float sectorlight = cluster.lightSourceIntensity();
Expand All @@ -1326,25 +1325,26 @@ void Rend_RadioSubspaceEdges(ConvexSubspace const &subspace)

// We need to check all the shadow lines linked to this subspace for
// the purpose of fakeradio shadowing.
foreach(LineSide *side, shadowLines)
subspace.forAllShadowLines([&cluster, &shadowDark, &eyeToSurface] (LineSide &side)
{
// Already rendered during the current frame? We only want to
// render each shadow once per frame.
if(side->shadowVisCount() != R_FrameCount())
if(side.shadowVisCount() != R_FrameCount())
{
side->setShadowVisCount(R_FrameCount());
side.setShadowVisCount(R_FrameCount());

for(int pln = 0; pln < cluster.visPlaneCount(); ++pln)
{
Plane const &plane = cluster.visPlane(pln);
if(Vector3f(eyeToSurface, Rend_EyeOrigin().y - plane.heightSmoothed())
.dot(plane.surface().normal()) >= 0)
{
writeShadowSection(pln, *side, shadowDark);
writeShadowSection(pln, side, shadowDark);
}
}
}
}
return LoopContinue;
});
}

#ifdef DENG_DEBUG
Expand Down

0 comments on commit b1e63eb

Please sign in to comment.