Skip to content

Commit

Permalink
Polyobj: API improvements
Browse files Browse the repository at this point in the history
Encapsulated (un)linking of the polyobj from the owning GameMap and
revised linking so that the BSP leaf in which the polyobj is linked
is updated at this time.
  • Loading branch information
danij-deng committed May 11, 2013
1 parent d4ec052 commit 26b5ce5
Show file tree
Hide file tree
Showing 12 changed files with 163 additions and 69 deletions.
2 changes: 1 addition & 1 deletion doomsday/api/dd_share.h
Expand Up @@ -702,7 +702,7 @@ enum { MX, MY, MZ };
#define DD_BASE_POLYOBJ_ELEMENTS() \
DD_BASE_DDMOBJ_ELEMENTS() \
\
BspLeaf *bspLeaf; /* bspLeaf in which this resides */ \
BspLeaf *_bspLeaf; /* bspLeaf in which this resides */ \
int _indexInMap; \
int tag; /* Reference tag. */ \
int validCount; \
Expand Down
25 changes: 20 additions & 5 deletions doomsday/client/include/map/line.h
Expand Up @@ -31,6 +31,7 @@
#include <de/Vector>

#include "MapElement"
#include "Polyobj"
#include "Surface"
#include "Vertex"

Expand Down Expand Up @@ -63,6 +64,9 @@ class Line : public de::MapElement
/// Required sector attribution is missing. @ingroup errors
DENG2_ERROR(MissingSectorError);

/// Required polyobj attribution is missing. @ingroup errors
DENG2_ERROR(MissingPolyobjError);

/// The given side section identifier is invalid. @ingroup errors
DENG2_ERROR(InvalidSectionIdError);

Expand Down Expand Up @@ -740,16 +744,27 @@ class Line : public de::MapElement
}

/**
* Returns @c true iff the line is part of some Polyobj.
* Returns @c true iff the line defines a section of some Polyobj.
*/
bool definesPolyobj() const;

/**
* Returns the Polyobj for which the line is a defining section.
*
* @see definesPolyobj()
*/
bool isFromPolyobj() const;
Polyobj &polyobj() const;

/**
* Mark the line as being owned by/is part of some Polyobj.
* Change the attributed polyobj which owns the line.
*
* @param set @c true to set, @c false to clear.
* @param newOwner New polyobj to attribute as the to the line. Can be
* @c 0, to clear the attribution. (Note that the polyobj
* may also represent this relationship, so the relevant
* method(s) of Polyobj will also need to be called to
* complete the job of removing this relationship.)
*/
void markPolyobjOwned(bool set = true);
void setPolyobj(Polyobj *newOwner);

/**
* Returns @c true iff the line resulted in the creation of a BSP window
Expand Down
34 changes: 34 additions & 0 deletions doomsday/client/include/map/polyobj.h
Expand Up @@ -41,6 +41,9 @@ class Vertex;
typedef struct polyobj_s
{
public:
/// The polyobj is not presently linked in the BSP. @ingroup errors
DENG2_ERROR(NotLinkedError);

typedef QList<Line *> Lines;
typedef QList<Vertex *> Vertexes;

Expand All @@ -55,6 +58,37 @@ typedef struct polyobj_s
/// @note: Does nothing about the user data section.
~polyobj_s();

/**
* Returns @c true if the polyobj is presently linked in the owning GameMap.
*/
bool isLinked();

/**
* (Re)link the polyobj in the owning GameMap. Ownership is not affected.
* To be called @em after rotation and/or translation to re-link the polyobj
* and thereby complete the process.
*
* Linking only occurs if the polyobj is not presently linked (subsequent calls
* are ignored).
*/
void link();

/**
* Unlink the polyobj in the owning GameMap. To be called @em before attempting
* to rotate and/or translate the polyobj to initiate the process.
*
* Unlinking only occurs if the polyobj is presently linked (subsequent calls
* are ignored).
*/
void unlink();

/**
* Returns the BSP leaf in which the polyobj is presently linked.
*
* @see isLinked();
*/
BspLeaf &bspLeaf() const;

/**
* Returns the sound emitter for the polyobj.
*/
Expand Down
4 changes: 2 additions & 2 deletions doomsday/client/src/edit_map.cpp
Expand Up @@ -1121,7 +1121,7 @@ int MPE_PolyobjCreate(int *lines, int lineCount, int tag, int sequenceType,
if(lines[i] < 0 || lines[i] >= editMap.lines.count()) return -1;

Line *line = editMap.lines[lines[i]];
if(line->isFromPolyobj()) return -1;
if(line->definesPolyobj()) return -1;
}

Polyobj *po = editMap.createPolyobj(Vector2d(originX, originY));
Expand All @@ -1133,7 +1133,7 @@ int MPE_PolyobjCreate(int *lines, int lineCount, int tag, int sequenceType,
Line *line = editMap.lines[lines[i]];

// This line belongs to a polyobj.
line->markPolyobjOwned();
line->setPolyobj(po);
static_cast<Polyobj::Lines *>(po->_lines)->append(line);
}

Expand Down
4 changes: 2 additions & 2 deletions doomsday/client/src/map/bsp/partitioner.cpp
Expand Up @@ -265,7 +265,7 @@ DENG2_PIMPL(Partitioner)

bool lineMightHaveWindowEffect(Line const &line)
{
if(line.isFromPolyobj()) return false;
if(line.definesPolyobj()) return false;
if(line.hasFrontSector() && line.hasBackSector()) return false;
if(!line.hasFrontSector()) return false;
//if(line.hasZeroLength() || line._buildData.overlap) return false;
Expand Down Expand Up @@ -375,7 +375,7 @@ DENG2_PIMPL(Partitioner)
foreach(Line *line, map->lines())
{
// Polyobj lines are completely ignored.
if(line->isFromPolyobj()) continue;
if(line->definesPolyobj()) continue;

LineSegment *front = 0;
coord_t angle = 0;
Expand Down
28 changes: 3 additions & 25 deletions doomsday/client/src/map/gamemap.cpp
Expand Up @@ -829,35 +829,13 @@ void GameMap::initPolyobjs()

foreach(Polyobj *po, _polyobjs)
{
// Find the center point of the polyobj.
Vector2d avg;
foreach(Line *line, po->lines())
{
avg += line->fromOrigin();
}
avg /= po->lineCount();

// Given the center point determine in which BSP leaf the polyobj resides.
if(BspLeaf *bspLeaf = bspLeafAtPoint(avg))
{
if(bspLeaf->hasPolyobj())
{
LOG_WARNING("Multiple polyobjs in a single BSP leaf\n"
" (BSP leaf %i, sector %i). Previous polyobj overridden.")
<< bspLeaf->indexInMap()
<< bspLeaf->sector().indexInMap();
}
bspLeaf->setFirstPolyobj(po);
po->bspLeaf = bspLeaf;
}

/// @todo Is this still necessary? -ds
/// (This data is updated automatically when moving/rotating).
po->updateAABox();
po->updateSurfaceTangents();

P_PolyobjUnlink(po);
P_PolyobjLink(po);
po->unlink();
po->link();
}
}

Expand Down Expand Up @@ -1055,7 +1033,7 @@ void GameMap::linkLine(Line &line)
DENG_ASSERT(lineBlockmap != 0);

// Lines of Polyobjs don't get into the blockmap (presently...).
if(line.isFromPolyobj()) return;
if(line.definesPolyobj()) return;

vec2d_t origin; V2d_Copy(origin, Blockmap_Origin(lineBlockmap));
vec2d_t cellSize; V2d_Copy(cellSize, Blockmap_CellSize(lineBlockmap));
Expand Down
25 changes: 18 additions & 7 deletions doomsday/client/src/map/line.cpp
Expand Up @@ -26,6 +26,7 @@
#include <de/Vector>

#include "m_misc.h"

#include "Sector"
#include "Vertex"

Expand Down Expand Up @@ -490,8 +491,8 @@ DENG2_PIMPL(Line)
Side front;
Side back;

/// @c true= the line is owned by some Polyobj.
bool polyobjOwned;
/// The polyobj which this line defines a section of, if any.
Polyobj *polyobj;

/// Used by legacy algorithms to prevent repeated processing.
int validCount;
Expand All @@ -511,7 +512,7 @@ DENG2_PIMPL(Line)
length(direction.length()),
front(*i, frontSector),
back(*i, backSector),
polyobjOwned(false),
polyobj(0),
validCount(0)
{
std::memset(mapped, 0, sizeof(mapped));
Expand Down Expand Up @@ -559,14 +560,24 @@ bool Line::isBspWindow() const
return _bspWindowSector != 0;
}

bool Line::isFromPolyobj() const
bool Line::definesPolyobj() const
{
return d->polyobj != 0;
}

Polyobj &Line::polyobj() const
{
return d->polyobjOwned;
if(d->polyobj)
{
return *d->polyobj;
}
/// @throw Line::MissingPolyobjError Attempted with no polyobj attributed.
throw Line::MissingPolyobjError("Line::polyobj", "No polyobj is attributed");
}

void Line::markPolyobjOwned(bool set)
void Line::setPolyobj(Polyobj *newOwner)
{
d->polyobjOwned = set;
d->polyobj = newOwner;
}

Line::Side &Line::side(int back)
Expand Down
6 changes: 2 additions & 4 deletions doomsday/client/src/map/p_dmu.cpp
Expand Up @@ -2245,16 +2245,14 @@ DENG_EXTERN_C void P_SetPolyobjCallback(void (*func) (struct mobj_s *, void *, v
DENG_EXTERN_C void P_PolyobjUnlink(Polyobj *po)
{
if(!po) return;
/// @todo Do not assume polyobj is from the CURRENT map.
theMap->unlinkPolyobj(*po);
po->unlink();
}

#undef P_PolyobjLink
DENG_EXTERN_C void P_PolyobjLink(Polyobj *po)
{
if(!po) return;
/// @todo Do not assume polyobj is from the CURRENT map.
theMap->linkPolyobj(*po);
po->link();
}

#undef P_PolyobjByID
Expand Down

0 comments on commit 26b5ce5

Please sign in to comment.