- rewrote the remaining parts of clipmove's wall collector.

This commit is contained in:
Christoph Oelckers 2022-10-23 12:29:32 +02:00
parent c2a2743872
commit 3e3df527d2
3 changed files with 96 additions and 45 deletions

View file

@ -116,6 +116,19 @@ static void addclipline(int32_t dax1, int32_t day1, int32_t dax2, int32_t day2,
clipnum++;
}
void addClipLine(MoveClipper& clip, const DVector2& start, const DVector2& end, const CollisionBase& daoval, int nofix)
{
addclipline(int(start.X * worldtoint), int(start.Y * worldtoint), int(end.X * worldtoint), int(end.Y * worldtoint), daoval, nofix);
}
void addClipSect(MoveClipper& clip, int sec)
{
if (!clipsectormap[sec])
addclipsect(sec);
}
//
// raytrace (internal)
//
@ -246,50 +259,10 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect,
do
{
int const dasect = clipsectorlist[clipsectcnt++];
////////// Walls //////////
auto const sec = &sector[dasect];
for (auto& wal : sec->walls)
{
clip.pos = { pos->X * inttoworld, pos->Y * inttoworld, pos->Z * zinttoworld };
int clipyou = checkClipWall(clip, &wal);
if (clipyou == -1) continue;
if (clipyou)
{
vec2_t p1 = wal.wall_int_pos();
vec2_t p2 = wal.point2Wall()->wall_int_pos();
vec2_t d = { p2.X - p1.X, p2.Y - p1.Y };
CollisionBase objtype;
objtype.setWall(&wal);
//Add 2 boxes at endpoints
int32_t bsz = walldist; if (diff.X < 0) bsz = -bsz;
addclipline(p1.X-bsz, p1.Y-bsz, p1.X-bsz, p1.Y+bsz, objtype, false);
addclipline(p2.X-bsz, p2.Y-bsz, p2.X-bsz, p2.Y+bsz, objtype, false);
bsz = walldist; if (diff.Y < 0) bsz = -bsz;
addclipline(p1.X+bsz, p1.Y-bsz, p1.X-bsz, p1.Y-bsz, objtype, false);
addclipline(p2.X+bsz, p2.Y-bsz, p2.X-bsz, p2.Y-bsz, objtype, false);
vec2_t v;
v.X = walldist; if (d.Y > 0) v.X = -v.X;
v.Y = walldist; if (d.X < 0) v.Y = -v.Y;
if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE && d.X * (pos->Y-p1.Y-v.Y) < (pos->X-p1.X-v.X) * d.Y)
v.X >>= 1, v.Y >>= 1;
addclipline(p1.X+v.X, p1.Y+v.Y, p2.X+v.X, p2.Y+v.Y, objtype, false);
}
else if (wal.nextsector>=0)
{
if (!clipsectormap[wal.nextsector])
addclipsect(wal.nextsector);
}
}
////////// Walls //////////
addWallsToClipList(clip, &sector[dasect]);
if (clipmove_warned & 1)
Printf("clipsectnum >= MAXCLIPSECTORS!\n");

View file

@ -1230,7 +1230,7 @@ int pushmove(DVector3& pos, sectortype** pSect, double walldist, double ceildist
//
//==========================================================================
int checkClipWall(const MoveClipper& clip, walltype* wal)
static int checkClipWall(const MoveClipper& clip, walltype* wal)
{
auto wal2 = wal->point2Wall();
auto waldelta = wal->delta();
@ -1256,6 +1256,81 @@ int checkClipWall(const MoveClipper& clip, walltype* wal)
}
}
//==========================================================================
//
// To produce reproducable results, this of course needs to add the exact same
// segments to the clipper as Build originally did,
// even though this looks ripe for optimization.
//
//==========================================================================
static void addWallToClipSet(MoveClipper& clip, walltype* wal)
{
CollisionBase objtype;
objtype.setWall(wal);
auto startpt = wal->pos;
auto endpt = wal->point2Wall()->pos;
//Add caps around the wall's end points. Results may be a bit weird when moving in cardinal directions!
double waldist = clip.walldist;
if (clip.moveDelta.X < 0) waldist = -waldist;
DVector2 distv1(-waldist, -waldist);
DVector2 distv2(-waldist, waldist);
addClipLine(clip, startpt + distv1, startpt + distv2, objtype);
addClipLine(clip, endpt + distv1, endpt + distv2, objtype);
waldist = clip.walldist;
if (clip.moveDelta.Y < 0) waldist = -waldist;
distv1 = { waldist, -waldist };
distv2 = { -waldist, -waldist };
addClipLine(clip, startpt + distv1, startpt + distv2, objtype);
addClipLine(clip, endpt + distv1, endpt + distv2, objtype);
// this is actually a very poor concept of 'distance' being used...
distv1 = { clip.walldist, clip.walldist };
if (wal->delta().Y > 0) distv1.X = -distv1.X;
if (wal->delta().X < 0) distv1.Y = -distv1.Y;
#if 0
// What EDuke32 added here, this doesn't seem to make much sense
// because it leaves gaps in the path from the 5 line segments being added here
if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE)
{
if (wal->delta().RotatedCCW().dot(pos - startpt - distv1) < 0)
v *= 0.5;
}
#endif
addClipLine(clip, startpt + distv1, endpt + distv1, objtype);
}
//==========================================================================
//
//
//
//==========================================================================
void addWallsToClipList(MoveClipper& clip, sectortype* sec)
{
for(auto& wal : sec->walls)
{
int result = checkClipWall(clip, &wal);
if (result == 1)
{
addWallToClipSet(clip, &wal);
}
else if (result == 0)
{
addClipSect(clip, wal.nextsector);
}
}
}
//==========================================================================
//
//

View file

@ -252,7 +252,10 @@ struct MoveClipper
double walldist;
};
int checkClipWall(const MoveClipper& clip, walltype* wal);
void addClipLine(MoveClipper& clip, const DVector2& start, const DVector2& end, const CollisionBase& daoval, int nofix = false);
void addClipSect(MoveClipper& clip, int sec);
void addWallsToClipList(MoveClipper& clip, sectortype* sec);
int FindBestSector(const DVector3& pos);