- replaced dragpoint (both the generic and the Blood variant) with a newly written vertexscan function.

This is a template allowing to run any task on a set of walls with equivalent start point.
Code was redesigned from scratch to be more clear than the existing variants.

The idea here is to reuse the base algorithm for other things that need to operate on the equivalent set of a given wall's start point.
This commit is contained in:
Christoph Oelckers 2021-12-28 13:43:25 +01:00
parent c8b5fa6556
commit 3fee8f3c4e
5 changed files with 56 additions and 93 deletions

View file

@ -263,7 +263,6 @@ void neartag(const vec3_t& pos, sectortype* sect, int angle, HitInfoBase& result
int cansee(int x1, int y1, int z1, sectortype* sect1, int x2, int y2, int z2, sectortype* sect2);
int32_t inside(int32_t x, int32_t y, const sectortype* sectnum);
void dragpoint(int pointhighlight, int32_t dax, int32_t day);
int32_t try_facespr_intersect(uspriteptr_t const spr, vec3_t const in,
int32_t vx, int32_t vy, int32_t vz,
vec3_t * const intp, int32_t strictly_smaller_than_p);

View file

@ -608,61 +608,6 @@ void neartag(const vec3_t& sv, sectortype* sect, int ange, HitInfoBase& result,
}
//
// dragpoint
//
void dragpoint(int w, int32_t dax, int32_t day)
{
BFSSearch walbitmap(wall.Size());
int clockwise = 0;
const int tmpstartwall = w;
int cnt = 16384; // limit the number of iterations.
while (1)
{
auto wal = &wall[w];
wal->move(dax, day);
walbitmap.Set(w);
if (!clockwise) //search points CCW
{
if (wal->nextwall >= 0)
w = wall[wal->nextwall].point2;
else
{
w = tmpstartwall;
clockwise = 1;
}
}
cnt--;
if (cnt==0)
{
Printf("dragpoint %d: infinite loop!\n", w);
break;
}
if (clockwise)
{
auto thelastwall = wall[w].lastWall();
if (thelastwall->nextwall >= 0)
w = thelastwall->nextwall;
else
break;
}
if (walbitmap.Check(w))
{
if (clockwise)
break;
w = tmpstartwall;
clockwise = 1;
continue;
}
}
}
////////// UPDATESECTOR* FAMILY OF FUNCTIONS //////////
/* Different "is inside" predicates.

View file

@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "gamestruct.h"
#include "intvec.h"
#include "coreactor.h"
#include "interpolate.h"
//---------------------------------------------------------------------------
//
@ -385,6 +386,20 @@ bool sectorsConnected(int sect1, int sect2)
return false;
}
//==========================================================================
//
//
//
//==========================================================================
void dragpoint(walltype* startwall, int newx, int newy)
{
vertexscan(startwall, [&](walltype* wal)
{
wal->move(newx, newy);
});
}
//==========================================================================
//
// vector serializers

View file

@ -112,6 +112,42 @@ public:
}
};
//==========================================================================
//
// scans all vertices equivalent with a given spot and performs some work on them.
//
//==========================================================================
template<class func>
void vertexscan(walltype* startwall, func mark)
{
BFSSearch walbitmap(wall.Size());
// first pass: scan the the next-in-loop of the partner
auto wal = startwall;
do
{
mark(wal);
walbitmap.Set(wall.IndexOf(wal));
if (wal->nextwall < 0) break;
wal = wal->nextWall()->point2Wall();
} while (!walbitmap.Check(wall.IndexOf(wal)));
// second pass: scan the partner of the previous-in-loop.
wal = startwall;
while (true)
{
auto thelastwall = wal->lastWall();
if (!thelastwall->twoSided()) break;
wal = thelastwall->nextWall();
if (walbitmap.Check(wall.IndexOf(wal))) break;
mark(wal);
walbitmap.Set(wall.IndexOf(wal));
}
}
extern int cameradist, cameraclock;
void loaddefinitionsfile(const char* fn, bool cumulative = false, bool maingrp = false);
@ -130,6 +166,7 @@ void GetFlatSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out, bool
void GetFlatSpritePosition(const tspritetype* spr, vec2_t pos, vec2_t* out, int* outz = nullptr, bool render = false);
void checkRotatedWalls();
bool sectorsConnected(int sect1, int sect2);
void dragpoint(walltype* wal, int newx, int newy);
// y is negated so that the orientation is the same as in GZDoom, in order to use its utilities.
// The render code should NOT use Build coordinates for anything!
@ -322,11 +359,6 @@ inline double SquareDistToWall(double px, double py, const walltype* wal)
return SquareDist(px, py, lx1 + t * (lx2 - lx1), ly1 + t * (ly2 - ly1));
}
inline void dragpoint(walltype* pointhighlight, int32_t dax, int32_t day)
{
dragpoint(wallnum(pointhighlight), dax, day);
}
inline void alignceilslope(sectortype* sect, int x, int y, int z)
{
sect->setceilingslope(getslopeval(sect, x, y, z, sect->ceilingz));

View file

@ -745,39 +745,11 @@ void PathSound(sectortype* pSector, int nSound)
void DragPoint(walltype* pWall, int x, int y)
{
viewInterpolateWall(pWall);
pWall->move(x, y);
int vsi = wall.Size();
auto prevWall = pWall;
do
{
if (prevWall->twoSided())
vertexscan(pWall, [&](walltype* wal)
{
prevWall = prevWall->nextWall()->point2Wall();
viewInterpolateWall(prevWall);
prevWall->move(x, y);
}
else
{
prevWall = pWall;
do
{
auto lw = prevWall->lastWall();
if (lw && lw->twoSided())
{
prevWall = lw->nextWall();
viewInterpolateWall(prevWall);
prevWall->move(x, y);
}
else
break;
vsi--;
} while (prevWall != pWall && vsi > 0);
break;
}
vsi--;
} while (prevWall != pWall && vsi > 0);
viewInterpolateWall(wal);
wal->move(x, y);
});
}
void TranslateSector(sectortype* pSector, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11, char a12)