From b31e6c0bdfd29a0e20df236c7bfe46b110e93669 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 4 Aug 2022 23:47:29 +0200 Subject: [PATCH] - replaced getclosestpointonwall_internal with a floating point version based on NearestPointLine. --- source/build/include/build.h | 12 ----------- source/build/src/clip.cpp | 7 +++++++ source/build/src/engine.cpp | 38 ++-------------------------------- source/core/gamefuncs.cpp | 40 ++++++++++++++++++++++++++++++++++++ source/core/gamefuncs.h | 23 ++++++++++++++++----- source/core/gameinput.cpp | 3 +-- 6 files changed, 68 insertions(+), 55 deletions(-) diff --git a/source/build/include/build.h b/source/build/include/build.h index 8758d8baf1c..756e7f41eec 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -87,7 +87,6 @@ enum { #include "maptypes.h" #include "clip.h" -int32_t getwalldist(vec2_t const in, int const wallnum); int32_t getwalldist(vec2_t const in, int const wallnum, vec2_t * const out); EXTERN int32_t guniqhudid; @@ -207,17 +206,6 @@ inline sectortype* safenextsectorneighborzptr(sectortype* sectp, int refz, int t return sect == nullptr ? sectp : sect; } -int getceilzofslopeptr(const sectortype* sec, int dax, int day) ATTRIBUTE((nonnull(1))); -int getflorzofslopeptr(const sectortype* sec, int dax, int day) ATTRIBUTE((nonnull(1))); -void getzsofslopeptr(const sectortype* sec, int dax, int day, int *ceilz, int *florz) ATTRIBUTE((nonnull(1,4,5))); - -inline void getcorrectzsofslope(int sectnum, int32_t dax, int32_t day, int32_t *ceilz, int32_t *florz) -{ - vec2_t closest = { dax, day }; - getsectordist(closest, sectnum, &closest); - getzsofslopeptr(§or[sectnum], closest.X, closest.Y, ceilz, florz); -} - int32_t lintersect(int32_t originX, int32_t originY, int32_t originZ, int32_t destX, int32_t destY, int32_t destZ, int32_t lineStartX, int32_t lineStartY, int32_t lineEndX, int32_t lineEndY, diff --git a/source/build/src/clip.cpp b/source/build/src/clip.cpp index 6cfadbc5e88..78ab897fb33 100644 --- a/source/build/src/clip.cpp +++ b/source/build/src/clip.cpp @@ -393,6 +393,13 @@ static int get_floorspr_clipyou(vec2_t const v1, vec2_t const v2, vec2_t const v return clipyou; } +static int32_t getwalldist(vec2_t const in, int const wallnum) +{ + auto dvec = NearestPointOnWall(in.X * maptoworld, in.Y * maptoworld, &wall[wallnum]); + vec2_t closest = { int(dvec.X * worldtoint), int(dvec.Y * worldtoint) }; + return abs(closest.X - in.X) + abs(closest.Y - in.Y); +} + static void clipupdatesector(vec2_t const pos, int * const sectnum, int walldist) { #if 0 diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index cda420de3b1..27b409e9b42 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -45,34 +45,6 @@ uint8_t globalr = 255, globalg = 255, globalb = 255; static int16_t radarang[1280]; -// adapted from build.c -static void getclosestpointonwall_internal(vec2_t const p, int32_t const dawall, vec2_t *const closest) -{ - vec2_t const w = wall[dawall].wall_int_pos(); - vec2_t const w2 = wall[dawall].point2Wall()->wall_int_pos(); - vec2_t const d = { w2.X - w.X, w2.Y - w.Y }; - - int64_t i = d.X * ((int64_t)p.X - w.X) + d.Y * ((int64_t)p.Y - w.Y); - - if (i <= 0) - { - *closest = w; - return; - } - - int64_t const j = (int64_t)d.X * d.X + (int64_t)d.Y * d.Y; - - if (i >= j) - { - *closest = w2; - return; - } - - i = ((i << 15) / j) << 15; - - *closest = { (int32_t)(w.X + ((d.X * i) >> 30)), (int32_t)(w.Y + ((d.Y * i) >> 30)) }; -} - // // Internal Engine Functions @@ -491,16 +463,10 @@ static inline int inside_z_p(int32_t const x, int32_t const y, int32_t const z, return (z >= cz && z <= fz && inside_p(x, y, sectnum)); } -int32_t getwalldist(vec2_t const in, int const wallnum) -{ - vec2_t closest; - getclosestpointonwall_internal(in, wallnum, &closest); - return abs(closest.X - in.X) + abs(closest.Y - in.Y); -} - int32_t getwalldist(vec2_t const in, int const wallnum, vec2_t * const out) { - getclosestpointonwall_internal(in, wallnum, out); + auto dvec = NearestPointOnWall(in.X * maptoworld, in.Y * maptoworld, &wall[wallnum]); + *out = { int(dvec.X * worldtoint), int(dvec.Y * worldtoint) }; return abs(out->X - in.X) + abs(out->Y - in.Y); } diff --git a/source/core/gamefuncs.cpp b/source/core/gamefuncs.cpp index bcb005035dd..c9703ed25fa 100644 --- a/source/core/gamefuncs.cpp +++ b/source/core/gamefuncs.cpp @@ -220,6 +220,16 @@ void getzsofslopeptr(const sectortype* sec, int dax, int day, int* ceilz, int* f *florz = int(f); } +void getcorrectzsofslope(int sectnum, int dax, int day, int* ceilz, int* florz) +{ + DVector2 closestv; + SquareDistToSector(dax * inttoworld, day * inttoworld, §or[sectnum], &closestv); + float ffloorz, fceilz; + calcSlope(§or[sectnum], closestv.X * worldtoint, closestv.Y * worldtoint, &fceilz, &ffloorz); + if (ceilz) *ceilz = int(fceilz); + if (florz) *florz = int(ffloorz); +} + //========================================================================== // // @@ -234,6 +244,36 @@ int getslopeval(sectortype* sect, int x, int y, int z, int basez) return i == 0? 0 : Scale((z - basez) << 8, wal->Length(), i); } +//========================================================================== +// +// Calculate the distance to the closest point in the given sector +// +//========================================================================== + +double SquareDistToSector(double px, double py, const sectortype* sect, DVector2* point) +{ + if (inside(px, py, sect)) + { + if (point) + *point = { px, py }; + return 0; + } + + double bestdist = DBL_MAX; + DVector2 bestpt = { px, py }; + for (auto& wal : wallsofsector(sect)) + { + DVector2 pt; + auto dist = SquareDistToWall(px, py, &wal, &pt); + if (dist < bestdist) + { + bestdist = dist; + bestpt = pt; + } + } + if (point) *point = bestpt; + return bestdist; +} //========================================================================== // diff --git a/source/core/gamefuncs.h b/source/core/gamefuncs.h index f59e620e823..fbfdfd62c32 100644 --- a/source/core/gamefuncs.h +++ b/source/core/gamefuncs.h @@ -174,6 +174,10 @@ void dragpoint(walltype* wal, int newx, int newy); void dragpoint(walltype* wal, const DVector2& pos); DVector2 rotatepoint(const DVector2& pivot, const DVector2& point, binangle angle); int32_t inside(double x, double y, const sectortype* sect); +void getcorrectzsofslope(int sectnum, int dax, int day, int* ceilz, int* florz); +int getceilzofslopeptr(const sectortype* sec, int dax, int day); +int getflorzofslopeptr(const sectortype* sec, int dax, int day); +void getzsofslopeptr(const sectortype* sec, int dax, int day, int* ceilz, int* florz); // y is negated so that the orientation is the same as in GZDoom, in order to use its utilities. @@ -374,7 +378,7 @@ inline DVector2 NearestPointLine(double px, double py, const walltype* wal) return { xx, yy }; } -inline double SquareDistToWall(double px, double py, const walltype* wal, DVector2* point = nullptr) +inline DVector2 NearestPointOnWall(double px, double py, const walltype* wal) { double lx1 = wal->pos.X; double ly1 = wal->pos.Y; @@ -383,16 +387,25 @@ inline double SquareDistToWall(double px, double py, const walltype* wal, DVecto double wall_length = SquareDist(lx1, ly1, lx2, ly2); - if (wall_length == 0) return SquareDist(px, py, lx1, ly1); + if (wall_length == 0) return { lx1, ly1 }; double t = ((px - lx1) * (lx2 - lx1) + (py - ly1) * (ly2 - ly1)) / wall_length; - t = clamp(t, 0., 1.); + if (t <= 0) return { lx1, ly1 }; + if (t >= 1) return { lx2, ly2 }; double xx = lx1 + t * (lx2 - lx1); double yy = ly1 + t * (ly2 - ly1); - if (point) *point = { xx, yy }; - return SquareDist(px, py, xx, yy); + return { xx, yy }; } +inline double SquareDistToWall(double px, double py, const walltype* wal, DVector2* point = nullptr) +{ + auto pt = NearestPointOnWall(px, py, wal); + if (point) *point = pt; + return SquareDist(px, py, pt.X, pt.Y); +} + +double SquareDistToSector(double px, double py, const sectortype* sect, DVector2* point = nullptr); + inline double SquareDistToLine(double px, double py, double lx1, double ly1, double lx2, double ly2) { double wall_length = SquareDist(lx1, ly1, lx2, ly2); diff --git a/source/core/gameinput.cpp b/source/core/gameinput.cpp index e0c35ef752b..e07eb00136b 100644 --- a/source/core/gameinput.cpp +++ b/source/core/gameinput.cpp @@ -25,8 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "gameinput.h" #include "gamestruct.h" #include "serializer.h" -#include "build.h" - +#include "gamefuncs.h" //--------------------------------------------------------------------------- //