Skip to content

Commit

Permalink
Refactor|Polyobj: Previous and original vertex coords use QVector<de:…
Browse files Browse the repository at this point in the history
…:Vector2d>

Plus cleanup.
  • Loading branch information
danij-deng committed Apr 16, 2013
1 parent 1350601 commit d1143de
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 80 deletions.
8 changes: 2 additions & 6 deletions doomsday/api/dd_share.h
Expand Up @@ -702,10 +702,6 @@ enum { MX, MY, MZ };
int health;\
mobjinfo_t *info; /* &mobjinfo[mobj->type] */

typedef struct povertex_s {
coord_t origin[2];
} povertex_t;

/// Base Polyobj elements. Games MUST use this as the basis for Polyobj. @ingroup map
#define DD_BASE_POLYOBJ_ELEMENTS() \
DD_BASE_DDMOBJ_ELEMENTS() \
Expand All @@ -721,8 +717,8 @@ typedef struct povertex_s {
angle_t angleSpeed; /* Rotation speed. */ \
void *_lines; \
void *_uniqueVertexes; \
struct povertex_s *originalPts; /* Used as the base for the rotations. */ \
struct povertex_s *prevPts; /* Use to restore the old point values. */ \
void *_originalPts; /* Used as the base for the rotations. */ \
void *_prevPts; /* Use to restore the old point values. */ \
double speed; /* Movement speed. */ \
boolean crush; /* Should the polyobj attempt to crush mobjs? */ \
int seqType; \
Expand Down
35 changes: 20 additions & 15 deletions doomsday/client/include/map/polyobj.h
Expand Up @@ -22,9 +22,6 @@
#define DENG_WORLD_MAP_POLYOBJ

#include <QList>
#include <QSet>

#include <de/vector1.h> /// @todo Remove me.

#include <de/Vector>

Expand All @@ -42,7 +39,7 @@ typedef struct polyobj_s
{
public:
typedef QList<Line *> Lines;
typedef QSet<Vertex *> Vertexes;
typedef QList<Vertex *> Vertexes;

public:
DD_BASE_POLYOBJ_ELEMENTS()
Expand All @@ -63,38 +60,46 @@ typedef struct polyobj_s
inline uint lineCount() const { return lines().count(); }

/**
* To be called once all Lines have been added in order to compile the set
* To be called once all Lines have been added in order to compile the list
* of unique vertexes for the polyobj. A vertex referenced by multiple lines
* is only included once in this set.
* is only included once in this list.
*/
void buildUniqueVertexes();

/**
* Provides access to the set of unique vertexes for the polyobj.
* Provides access to the list of unique vertexes for the polyobj.
*
* @see buildUniqueVertexSet()
* @see buildUniqueVertex()
*/
Vertexes const &uniqueVertexes() const;

/**
* Returns the total number of unique Vertexes for the polyobj.
*
* @see buildUniqueVertexSet()
* @see buildUniqueVertexes()
*/
inline uint uniqueVertexCount() const { return uniqueVertexes().count(); }

/**
* Update the original coordinates of all vertexes using the current coordinate
* values. To be called once initialization has completed to finalize the polyobj.
*
* @pre Unique vertex list has already been built.
*
* @see buildUniqueVertexes()
*/
void updateOriginalVertexCoords();

/**
* Translate the origin of the polyobj in the map coordinate space.
*
* @param delta Movement delta on the X|Y plane.
*/
bool move(const_pvec2d_t delta);
bool move(de::Vector2d const &delta);

/// @copydoc move()
inline bool move(coord_t x, coord_t y)
{
coord_t point[2] = { x, y };
return move(point);
inline bool move(coord_t x, coord_t y) {
return move(de::Vector2d(x, y));
}

/**
Expand Down Expand Up @@ -148,4 +153,4 @@ typedef struct polyobj_s

#define POLYOBJ_SIZE gx.polyobjSize

#endif // DENG_WORLD_MAP_POLYOB
#endif // DENG_WORLD_MAP_POLYOBJ
2 changes: 1 addition & 1 deletion doomsday/client/include/map/surface.h
@@ -1,4 +1,4 @@
/** @file surface.h Map surface.
/** @file surface.h World Map surface.
*
* @authors Copyright &copy; 2003-2013 Jaakko Keränen <jaakko.keranen@iki.fi>
* @authors Copyright &copy; 2006-2013 Daniel Swanson <danij@dengine.net>
Expand Down
10 changes: 1 addition & 9 deletions doomsday/client/src/edit_map.cpp
Expand Up @@ -916,15 +916,7 @@ boolean MPE_End()
}

polyobj->buildUniqueVertexes();
uint n = 0;
foreach(Vertex *vertex, polyobj->uniqueVertexes())
{
// The originalPts are relative to the polyobj origin.
vec2d_t const &vertexOrigin = vertex->origin();
polyobj->originalPts[n].origin[VX] = vertexOrigin[VX] - polyobj->origin[VX];
polyobj->originalPts[n].origin[VY] = vertexOrigin[VY] - polyobj->origin[VY];
n++;
}
polyobj->updateOriginalVertexCoords();
}

map->updateBounds();
Expand Down
2 changes: 2 additions & 0 deletions doomsday/client/src/map/p_polyobjs.cpp
Expand Up @@ -24,6 +24,8 @@

#include "map/gamemap.h"

using namespace de;

// Called when the polyobj hits a mobj.
static void (*po_callback) (mobj_t *mobj, void *line, void *polyobj);

Expand Down
129 changes: 80 additions & 49 deletions doomsday/client/src/map/polyobj.cpp
@@ -1,4 +1,4 @@
/** @file polyobj.cpp Moveable Polygonal Map-Object (Polyobj).
/** @file polyobj.cpp World Map Polyobj.
*
* @authors Copyright © 2003-2013 Jaakko Keränen <jaakko.keranen@iki.fi>
* @authors Copyright © 2006-2013 Daniel Swanson <danij@dengine.net>
Expand All @@ -18,20 +18,24 @@
* 02110-1301 USA</small>
*/

#include <de/Vector>
#include <QSet>
#include <QVector>

#include <de/memoryzone.h>
#include <de/vector1.h>

#include "de_base.h"
#include "de_console.h"
#include "de_play.h"
#include "de_misc.h"

#include "render/r_main.h" // validCount
#include "HEdge"

#include "map/polyobj.h"

using namespace de;

/// Used to store the original/previous vertex coordinates.
typedef QVector<Vector2d> VertexCoords;

static void notifyGeometryChanged(Polyobj &po)
{
#ifdef __CLIENT__
Expand Down Expand Up @@ -64,8 +68,8 @@ polyobj_s::polyobj_s(de::Vector2d const &origin_)
angleSpeed = 0;
_lines = new Lines;
_uniqueVertexes = new Vertexes;
originalPts = 0;
prevPts = 0;
_originalPts = new VertexCoords;
_prevPts = new VertexCoords;
speed = 0;
crush = false;
seqType = 0;
Expand All @@ -81,6 +85,8 @@ polyobj_s::~polyobj_s()

delete static_cast<Lines *>(_lines);
delete static_cast<Vertexes *>(_uniqueVertexes);
delete static_cast<VertexCoords *>(_originalPts);
delete static_cast<VertexCoords *>(_prevPts);
}

Polyobj::Lines const &Polyobj::lines() const
Expand All @@ -95,19 +101,31 @@ Polyobj::Vertexes const &Polyobj::uniqueVertexes() const

void Polyobj::buildUniqueVertexes()
{
QSet<Vertex *> vertexSet;
foreach(Line *line, lines())
{
vertexSet.insert(&line->v1());
vertexSet.insert(&line->v2());
}

Vertexes &uniqueVertexes = *static_cast<Vertexes *>(_uniqueVertexes);
uniqueVertexes = vertexSet.toList();

uniqueVertexes.clear();
// Resize the coordinate vectors as they are implicitly linked to the unique vertexes.
static_cast<VertexCoords *>(_originalPts)->resize(uniqueVertexes.count());
static_cast<VertexCoords *>(_prevPts)->resize(uniqueVertexes.count());
}

foreach(Line *line, lines())
void Polyobj::updateOriginalVertexCoords()
{
VertexCoords::iterator origCoordsIt = static_cast<VertexCoords *>(_originalPts)->begin();
foreach(Vertex *vertex, uniqueVertexes())
{
uniqueVertexes.insert(&line->v1());
uniqueVertexes.insert(&line->v2());
// The original coordinates are relative to the polyobj origin.
Vector2d &origCoords = *origCoordsIt;
origCoords = Vector2d(vertex->origin()) - Vector2d(origin);
origCoordsIt++;
}

// Resize the point arrays as they are implicitly linked to the unique vertexes.
originalPts = (povertex_t *) Z_Realloc(originalPts, uniqueVertexes.count() * sizeof(povertex_t), PU_MAP);
prevPts = (povertex_t *) Z_Realloc(prevPts, uniqueVertexes.count() * sizeof(povertex_t), PU_MAP);
}

void Polyobj::updateAABox()
Expand Down Expand Up @@ -155,7 +173,8 @@ static int PTR_CheckMobjBlocking(mobj_t *mo, void *context)
{
ptrmobjblockingparams_t *parms = (ptrmobjblockingparams_t *) context;

if(!mobjCanBlockMovement(mo)) return false;
if(!mobjCanBlockMovement(mo))
return false;

// Out of range?
AABoxd moBox(mo->origin[VX] - mo->radius,
Expand Down Expand Up @@ -208,28 +227,34 @@ static bool mobjIsBlockingPolyobj(Polyobj &po)
return false; // All clear.
}

bool Polyobj::move(const_pvec2d_t delta)
bool Polyobj::move(Vector2d const &delta)
{
LOG_AS("Polyobj::move");
//LOG_DEBUG("Applying delta %s to [%p]")
// << Vector2d(delta[VX], delta[VY]).asText() << this;
//LOG_DEBUG("Applying delta %s to [%p]") << delta.asText() << this;

P_PolyobjUnlink(this);
{
povertex_t *prevPtIt = prevPts;
VertexCoords::iterator prevCoordsIt = static_cast<VertexCoords *>(_prevPts)->begin();
foreach(Vertex *vertex, uniqueVertexes())
{
V2d_Copy(prevPtIt->origin, vertex->origin());
V2d_Sum(vertex->_origin, vertex->_origin, delta);
prevPtIt++;
// Remember the previous coords in case we need to undo.
(*prevCoordsIt) = vertex->origin();

// Apply translation.
Vector2d newVertexOrigin = Vector2d(vertex->origin()) + delta;
V2d_Set(vertex->_origin, newVertexOrigin.x, newVertexOrigin.y);

prevCoordsIt++;
}

foreach(Line *line, lines())
{
line->updateAABox();
}

V2d_Sum(origin, origin, delta);
Vector2d newOrigin = Vector2d(origin) + delta;
V2d_Set(origin, newOrigin.x, newOrigin.y);

updateAABox();
}
P_PolyobjLink(this);
Expand All @@ -241,19 +266,21 @@ bool Polyobj::move(const_pvec2d_t delta)

P_PolyobjUnlink(this);
{
povertex_t *prevPtIt = prevPts;
VertexCoords::const_iterator prevCoordsIt = static_cast<VertexCoords *>(_prevPts)->constBegin();
foreach(Vertex *vertex, uniqueVertexes())
{
V2d_Copy(vertex->_origin, prevPtIt->origin);
prevPtIt++;
V2d_Set(vertex->_origin, prevCoordsIt->x, prevCoordsIt->y);
prevCoordsIt++;
}

foreach(Line *line, lines())
{
line->updateAABox();
}

V2d_Subtract(origin, origin, delta);
Vector2d newOrigin = Vector2d(origin) - delta;
V2d_Set(origin, newOrigin.x, newOrigin.y);

updateAABox();
}
P_PolyobjLink(this);
Expand All @@ -267,20 +294,20 @@ bool Polyobj::move(const_pvec2d_t delta)
return true;
}

static void rotatePoint2d(coord_t point[2], coord_t const origin[2], uint fineAngle)
/**
* @param point Point to be rotated (in-place).
* @param about Origin to rotate @a point relative to.
* @param fineAngle Angle to rotate (theta).
*/
static void rotatePoint2d(Vector2d &point, Vector2d const &origin, uint fineAngle)
{
coord_t orig[2], rotated[2];
coord_t const c = FIX2DBL(fineCosine[fineAngle]);
coord_t const s = FIX2DBL(finesine[fineAngle]);

orig[VX] = point[VX];
orig[VY] = point[VY];
Vector2d orig = point;

rotated[VX] = orig[VX] * FIX2FLT(fineCosine[fineAngle]);
rotated[VY] = orig[VY] * FIX2FLT(finesine[fineAngle]);
point[VX] = rotated[VX] - rotated[VY] + origin[VX];

rotated[VX] = orig[VX] * FIX2FLT(finesine[fineAngle]);
rotated[VY] = orig[VY] * FIX2FLT(fineCosine[fineAngle]);
point[VY] = rotated[VY] + rotated[VX] + origin[VY];
point.x = orig.x * c - orig.y * s + origin.x;
point.y = orig.y * c + orig.x * s + origin.y;
}

bool Polyobj::rotate(angle_t delta)
Expand All @@ -293,17 +320,21 @@ bool Polyobj::rotate(angle_t delta)
{
uint fineAngle = (angle + delta) >> ANGLETOFINESHIFT;

povertex_t *originalPtIt = originalPts;
povertex_t *prevPtIt = prevPts;
VertexCoords::const_iterator origCoordsIt = static_cast<VertexCoords *>(_originalPts)->constBegin();
VertexCoords::iterator prevCoordsIt = static_cast<VertexCoords *>(_prevPts)->begin();
foreach(Vertex *vertex, uniqueVertexes())
{
V2d_Copy(prevPtIt->origin, vertex->origin());
V2d_Copy(vertex->_origin, originalPtIt->origin);
// Remember the previous coords in case we need to undo.
(*prevCoordsIt) = vertex->origin();

// Apply rotation relative to the "original" coords.
Vector2d newCoords = (*origCoordsIt);
rotatePoint2d(newCoords, origin, fineAngle);

rotatePoint2d(vertex->_origin, origin, fineAngle);
V2d_Set(vertex->_origin, newCoords.x, newCoords.y);

originalPtIt++;
prevPtIt++;
origCoordsIt++;
prevCoordsIt++;
}

foreach(Line *line, lines())
Expand All @@ -326,11 +357,11 @@ bool Polyobj::rotate(angle_t delta)

P_PolyobjUnlink(this);
{
povertex_t *prevPtIt = prevPts;
VertexCoords::const_iterator prevCoordsIt = static_cast<VertexCoords *>(_prevPts)->constBegin();
foreach(Vertex *vertex, uniqueVertexes())
{
V2d_Copy(vertex->_origin, prevPtIt->origin);
prevPtIt++;
V2d_Set(vertex->_origin, prevCoordsIt->x, prevCoordsIt->y);
prevCoordsIt++;
}

foreach(Line *line, lines())
Expand Down
1 change: 1 addition & 0 deletions doomsday/libdeng1/include/de/fixedpoint.h
Expand Up @@ -35,6 +35,7 @@
#define DBITS (FRACBITS-SLOPEBITS)

#define FIX2FLT(x) ( (x) / (float) FRACUNIT )
#define FIX2DBL(x) ( (double) FIX2FLT(x) )
#define Q_FIX2FLT(x) ( (float) ((x) >> FRACBITS) )
#define FLT2FIX(x) ( (fixed_t) ((x) * FRACUNIT) )
#define DBL2FIX(x) ( (fixed_t) FLT2FIX((float)(x)) )
Expand Down

0 comments on commit d1143de

Please sign in to comment.