From 3e3df527d2548e90f632914b4cbb103056a82456 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 23 Oct 2022 12:29:32 +0200 Subject: [PATCH] - rewrote the remaining parts of clipmove's wall collector. --- source/build/src/clip.cpp | 59 ++++++++---------------------- source/core/gamefuncs.cpp | 77 ++++++++++++++++++++++++++++++++++++++- source/core/gamefuncs.h | 5 ++- 3 files changed, 96 insertions(+), 45 deletions(-) diff --git a/source/build/src/clip.cpp b/source/build/src/clip.cpp index 86f9dad0e..1e9397214 100644 --- a/source/build/src/clip.cpp +++ b/source/build/src/clip.cpp @@ -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++]; - + clip.pos = { pos->X * inttoworld, pos->Y * inttoworld, pos->Z * zinttoworld }; + ////////// Walls ////////// - - auto const sec = §or[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); - } - } + addWallsToClipList(clip, §or[dasect]); if (clipmove_warned & 1) Printf("clipsectnum >= MAXCLIPSECTORS!\n"); diff --git a/source/core/gamefuncs.cpp b/source/core/gamefuncs.cpp index b71280983..3272a106b 100644 --- a/source/core/gamefuncs.cpp +++ b/source/core/gamefuncs.cpp @@ -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); + } + } +} + //========================================================================== // // diff --git a/source/core/gamefuncs.h b/source/core/gamefuncs.h index 4f9e51183..e92306288 100644 --- a/source/core/gamefuncs.h +++ b/source/core/gamefuncs.h @@ -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);