From d1143de8015cef91515ea0a9581465f4c552af0f Mon Sep 17 00:00:00 2001 From: danij Date: Tue, 16 Apr 2013 20:42:26 +0100 Subject: [PATCH] Refactor|Polyobj: Previous and original vertex coords use QVector Plus cleanup. --- doomsday/api/dd_share.h | 8 +- doomsday/client/include/map/polyobj.h | 35 +++--- doomsday/client/include/map/surface.h | 2 +- doomsday/client/src/edit_map.cpp | 10 +- doomsday/client/src/map/p_polyobjs.cpp | 2 + doomsday/client/src/map/polyobj.cpp | 129 ++++++++++++++-------- doomsday/libdeng1/include/de/fixedpoint.h | 1 + 7 files changed, 107 insertions(+), 80 deletions(-) diff --git a/doomsday/api/dd_share.h b/doomsday/api/dd_share.h index 374e5f5445..ac6b34aeb2 100644 --- a/doomsday/api/dd_share.h +++ b/doomsday/api/dd_share.h @@ -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() \ @@ -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; \ diff --git a/doomsday/client/include/map/polyobj.h b/doomsday/client/include/map/polyobj.h index 37e1bbf2ce..5eb968047e 100644 --- a/doomsday/client/include/map/polyobj.h +++ b/doomsday/client/include/map/polyobj.h @@ -22,9 +22,6 @@ #define DENG_WORLD_MAP_POLYOBJ #include -#include - -#include /// @todo Remove me. #include @@ -42,7 +39,7 @@ typedef struct polyobj_s { public: typedef QList Lines; - typedef QSet Vertexes; + typedef QList Vertexes; public: DD_BASE_POLYOBJ_ELEMENTS() @@ -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)); } /** @@ -148,4 +153,4 @@ typedef struct polyobj_s #define POLYOBJ_SIZE gx.polyobjSize -#endif // DENG_WORLD_MAP_POLYOB +#endif // DENG_WORLD_MAP_POLYOBJ diff --git a/doomsday/client/include/map/surface.h b/doomsday/client/include/map/surface.h index 73576279f1..9f8defe944 100644 --- a/doomsday/client/include/map/surface.h +++ b/doomsday/client/include/map/surface.h @@ -1,4 +1,4 @@ -/** @file surface.h Map surface. +/** @file surface.h World Map surface. * * @authors Copyright © 2003-2013 Jaakko Keränen * @authors Copyright © 2006-2013 Daniel Swanson diff --git a/doomsday/client/src/edit_map.cpp b/doomsday/client/src/edit_map.cpp index d2c9710d79..4779cee124 100644 --- a/doomsday/client/src/edit_map.cpp +++ b/doomsday/client/src/edit_map.cpp @@ -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(); diff --git a/doomsday/client/src/map/p_polyobjs.cpp b/doomsday/client/src/map/p_polyobjs.cpp index ba8025bd10..ee1144d20d 100644 --- a/doomsday/client/src/map/p_polyobjs.cpp +++ b/doomsday/client/src/map/p_polyobjs.cpp @@ -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); diff --git a/doomsday/client/src/map/polyobj.cpp b/doomsday/client/src/map/polyobj.cpp index 5994654c4e..3c8874fdbd 100644 --- a/doomsday/client/src/map/polyobj.cpp +++ b/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 * @authors Copyright © 2006-2013 Daniel Swanson @@ -18,13 +18,14 @@ * 02110-1301 USA */ -#include +#include +#include + +#include +#include #include "de_base.h" -#include "de_console.h" #include "de_play.h" -#include "de_misc.h" - #include "render/r_main.h" // validCount #include "HEdge" @@ -32,6 +33,9 @@ using namespace de; +/// Used to store the original/previous vertex coordinates. +typedef QVector VertexCoords; + static void notifyGeometryChanged(Polyobj &po) { #ifdef __CLIENT__ @@ -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; @@ -81,6 +85,8 @@ polyobj_s::~polyobj_s() delete static_cast(_lines); delete static_cast(_uniqueVertexes); + delete static_cast(_originalPts); + delete static_cast(_prevPts); } Polyobj::Lines const &Polyobj::lines() const @@ -95,19 +101,31 @@ Polyobj::Vertexes const &Polyobj::uniqueVertexes() const void Polyobj::buildUniqueVertexes() { + QSet vertexSet; + foreach(Line *line, lines()) + { + vertexSet.insert(&line->v1()); + vertexSet.insert(&line->v2()); + } + Vertexes &uniqueVertexes = *static_cast(_uniqueVertexes); + uniqueVertexes = vertexSet.toList(); - uniqueVertexes.clear(); + // Resize the coordinate vectors as they are implicitly linked to the unique vertexes. + static_cast(_originalPts)->resize(uniqueVertexes.count()); + static_cast(_prevPts)->resize(uniqueVertexes.count()); +} - foreach(Line *line, lines()) +void Polyobj::updateOriginalVertexCoords() +{ + VertexCoords::iterator origCoordsIt = static_cast(_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() @@ -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, @@ -208,20 +227,24 @@ 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(_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()) @@ -229,7 +252,9 @@ bool Polyobj::move(const_pvec2d_t delta) line->updateAABox(); } - V2d_Sum(origin, origin, delta); + Vector2d newOrigin = Vector2d(origin) + delta; + V2d_Set(origin, newOrigin.x, newOrigin.y); + updateAABox(); } P_PolyobjLink(this); @@ -241,11 +266,11 @@ bool Polyobj::move(const_pvec2d_t delta) P_PolyobjUnlink(this); { - povertex_t *prevPtIt = prevPts; + VertexCoords::const_iterator prevCoordsIt = static_cast(_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()) @@ -253,7 +278,9 @@ bool Polyobj::move(const_pvec2d_t delta) line->updateAABox(); } - V2d_Subtract(origin, origin, delta); + Vector2d newOrigin = Vector2d(origin) - delta; + V2d_Set(origin, newOrigin.x, newOrigin.y); + updateAABox(); } P_PolyobjLink(this); @@ -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) @@ -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(_originalPts)->constBegin(); + VertexCoords::iterator prevCoordsIt = static_cast(_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()) @@ -326,11 +357,11 @@ bool Polyobj::rotate(angle_t delta) P_PolyobjUnlink(this); { - povertex_t *prevPtIt = prevPts; + VertexCoords::const_iterator prevCoordsIt = static_cast(_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()) diff --git a/doomsday/libdeng1/include/de/fixedpoint.h b/doomsday/libdeng1/include/de/fixedpoint.h index b14ed44d6e..5e1b78ba10 100644 --- a/doomsday/libdeng1/include/de/fixedpoint.h +++ b/doomsday/libdeng1/include/de/fixedpoint.h @@ -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)) )