From faf98684a3bec496f0193bc77bc811a216dc6501 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 27 Oct 2022 09:29:08 +0200 Subject: [PATCH] - rewrote cliptrace. Completely new implementation reusing nothing of the original. # Conflicts: # source/build/src/clip.cpp # source/core/gamefuncs.cpp # source/core/gamefuncs.h --- source/core/gamefuncs.cpp | 60 +++++++++++++++++++++++++++++++++++++++ source/core/gamefuncs.h | 3 +- 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/source/core/gamefuncs.cpp b/source/core/gamefuncs.cpp index 3a909b508..ca2823377 100644 --- a/source/core/gamefuncs.cpp +++ b/source/core/gamefuncs.cpp @@ -1606,6 +1606,66 @@ void collectClipObjects(MoveClipper& clip, int spritemask) // //========================================================================== +int cliptrace(MoveClipper& clip, const DVector2& fpos, DVector2& fgoal) +{ + int32_t hitwall = -1; + + DVector2 move = fgoal - fpos; + double bestfactor = 1.; + ClipObject* bestclip = nullptr; + + for (auto& clipo : clip.clipobjects) + { + auto p1 = clipo.line.start; + auto delta = clipo.line.end - p1; + + double factor = InterceptLineSegments(fpos.X, fpos.Y, move.X, move.Y, p1.X, p1.Y, delta.X, delta.Y); + if (factor > 0 && factor < bestfactor) + { + bestfactor = factor; + bestclip = &clipo; + } + } + + DVector2 hit = fpos; + if (bestfactor < 1) + { + // account for math imprecisions and ensure that the resulting hit point is always at the front side of the line. + + auto p1 = bestclip->line.start; + auto delta = bestclip->line.end - p1; + double len = move.Length(); + move /= len; + bestfactor *= len; + + for (int i = 0; i < 256; i++) + { + hit = fpos + move * bestfactor; + // Do this on the original Build coordinate grid to avoid problems with expectations on the game side. + hit.X = xs_CRoundToInt(hit.X * worldtoint) * inttoworld; + hit.Y = xs_CRoundToInt(hit.Y * worldtoint) * inttoworld; + if (PointOnLineSide(hit.X, hit.Y, p1.X, p1.Y, delta.X, delta.Y) < 0) + { + hitwall = bestclip - clip.clipobjects.Data(); + break; + } + bestfactor -= maptoworld * 0.5; + if (bestfactor <= 0) break; + } + } + if (hitwall != -1) + { + fgoal = hit; + } + return hitwall; +} + +//========================================================================== +// +// +// +//========================================================================== + sectortype* FindSectorInSearchList(const DVector3& pos, BFSSectorSearch& search) { search.Rewind(); diff --git a/source/core/gamefuncs.h b/source/core/gamefuncs.h index a37023108..8a6ee066d 100644 --- a/source/core/gamefuncs.h +++ b/source/core/gamefuncs.h @@ -319,7 +319,8 @@ sectortype* FindSectorInSearchList(const DVector3& pos, BFSSectorSearch& search) void PushAway(MoveClipper &clip, DVector2& pos, sectortype* sect); void keepaway(MoveClipper& clip, DVector2& pos, ClipObject& clipo); -int FindBestSector(const DVector3& pos); + + tspritetype* renderAddTsprite(tspriteArray& tsprites, DCoreActor* actor);