From ede7a7ac1234aa827ed751d550d99e5494833ae2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 23 Oct 2022 20:35:01 +0200 Subject: [PATCH] - float version of clipmove's floor sprite collector. --- source/build/src/clip.cpp | 71 ++++----------------------------------- source/core/gamefuncs.cpp | 55 +++++++++++++++++++++++++++++- source/core/gamefuncs.h | 1 + 3 files changed, 62 insertions(+), 65 deletions(-) diff --git a/source/build/src/clip.cpp b/source/build/src/clip.cpp index 95defa402..58d67ce44 100644 --- a/source/build/src/clip.cpp +++ b/source/build/src/clip.cpp @@ -42,29 +42,6 @@ static inline int bcos(const int ang) ////////// CLIPMOVE ////////// inline uint8_t bitmap_test(uint8_t const* const ptr, int const n) { return ptr[n >> 3] & (1 << (n & 7)); } - -// x1, y1: in/out -// rest x/y: out -static inline void get_floorspr_points(DCoreActor *spr, int32_t px, int32_t py, - int32_t *x1, int32_t *x2, int32_t *x3, int32_t *x4, - int32_t *y1, int32_t *y2, int32_t *y3, int32_t *y4) -{ - DVector2 out[4]; - // very messed up interface... :( - GetFlatSpritePosition(spr, DVector2((*x1 - px) * inttoworld, (*y1 - py) * inttoworld), out); - *x1 = int(out[0].X * worldtoint); *y1 = int(out[0].Y * worldtoint); - *x2 = int(out[1].X * worldtoint); *y2 = int(out[1].Y * worldtoint); - *x3 = int(out[2].X * worldtoint); *y3 = int(out[2].Y * worldtoint); - *x4 = int(out[3].X * worldtoint); *y4 = int(out[3].Y * worldtoint); - -} - -inline int32_t spriteGetZOfSlope(const spritetypebase* tspr, int dax, int day, int heinum) -{ - return int(spriteGetZOfSlopef(tspr, DVector2(dax * inttoworld, day * inttoworld), heinum) * zworldtoint); -} - - // // clipinsideboxline // @@ -290,53 +267,19 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect, case CSTAT_SPRITE_ALIGNMENT_WALL: processClipWallSprite(clip, actor); + break; case CSTAT_SPRITE_ALIGNMENT_FLOOR: + processClipFloorSprite(clip, actor); + break; + case CSTAT_SPRITE_ALIGNMENT_SLOPE: { + + if (!processClipFloorSprite(clip, actor)) continue; int heinum = spriteGetSlope(actor); - int sz = spriteGetZOfSlope(&actor->spr, pos->X, pos->Y, heinum); - if (pos->Z > sz - flordist && pos->Z < sz + ceildist) - { - if ((cstat & CSTAT_SPRITE_ONE_SIDE) != 0) - if ((pos->Z > sz) == ((cstat & CSTAT_SPRITE_YFLIP)==0)) - continue; - - rxi[0] = p1.X; - ryi[0] = p1.Y; - - get_floorspr_points(actor, 0, 0, &rxi[0], &rxi[1], &rxi[2], &rxi[3], - &ryi[0], &ryi[1], &ryi[2], &ryi[3]); - - vec2_t v = { MulScale(bcos(actor->int_ang() - 256), walldist, 14), - MulScale(bsin(actor->int_ang() - 256), walldist, 14) }; - - if ((rxi[0]-pos->X) * (ryi[1]-pos->Y) < (rxi[1]-pos->X) * (ryi[0]-pos->Y)) - { - if (clipinsideboxline(cent.X, cent.Y, rxi[1], ryi[1], rxi[0], ryi[0], rad) != 0) - addclipline(rxi[1]-v.Y, ryi[1]+v.X, rxi[0]+v.X, ryi[0]+v.Y, obj, false); - } - else if ((rxi[2]-pos->X) * (ryi[3]-pos->Y) < (rxi[3]-pos->X) * (ryi[2]-pos->Y)) - { - if (clipinsideboxline(cent.X, cent.Y, rxi[3], ryi[3], rxi[2], ryi[2], rad) != 0) - addclipline(rxi[3]+v.Y, ryi[3]-v.X, rxi[2]-v.X, ryi[2]-v.Y, obj, false); - } - - if ((rxi[1]-pos->X) * (ryi[2]-pos->Y) < (rxi[2]-pos->X) * (ryi[1]-pos->Y)) - { - if (clipinsideboxline(cent.X, cent.Y, rxi[2], ryi[2], rxi[1], ryi[1], rad) != 0) - addclipline(rxi[2]-v.X, ryi[2]-v.Y, rxi[1]-v.Y, ryi[1]+v.X, obj, false); - } - else if ((rxi[3]-pos->X) * (ryi[0]-pos->Y) < (rxi[0]-pos->X) * (ryi[3]-pos->Y)) - { - if (clipinsideboxline(cent.X, cent.Y, rxi[0], ryi[0], rxi[3], ryi[3], rad) != 0) - addclipline(rxi[0]+v.X, ryi[0]+v.Y, rxi[3]+v.Y, ryi[3]-v.X, obj, false); - } - } - - if (heinum == 0) - continue; + if (heinum == 0) continue; // the rest is for slope sprites only. auto tex = TexMan.GetGameTexture(actor->spr.spritetexture()); diff --git a/source/core/gamefuncs.cpp b/source/core/gamefuncs.cpp index 1498eb563..76c575b71 100644 --- a/source/core/gamefuncs.cpp +++ b/source/core/gamefuncs.cpp @@ -1307,7 +1307,6 @@ static void addWallToClipSet(MoveClipper& clip, walltype* wal) #endif addClipLine(clip, startpt + distv1, endpt + distv1, objtype); - } //========================================================================== @@ -1411,6 +1410,60 @@ void processClipWallSprite(MoveClipper& clip, DCoreActor* actor) // //========================================================================== +bool processClipFloorSprite(MoveClipper& clip, DCoreActor* actor) +{ + int heinum = spriteGetSlope(actor); + double sprz = spriteGetZOfSlopef(&actor->spr, actor->spr.pos.XY(), heinum); + + if (clip.pos.Z > sprz - clip.floordist && clip.pos.Z < sprz + clip.ceilingdist) + { + if (actor->spr.cstat & CSTAT_SPRITE_ONE_SIDE) + { + if ((clip.pos.Z > sprz) == ((actor->spr.cstat & CSTAT_SPRITE_YFLIP) == 0)) return false; + } + + DVector2 points[4]; + GetFlatSpritePosition(actor, actor->spr.pos.XY(), points, nullptr); + + auto offset = (actor->spr.Angles.Yaw - DAngle45).ToVector() * clip.walldist; + + CollisionBase objtype; + objtype.setSprite(actor); + + DVector2 d[4]; + for (int i = 0; i < 4; i++) d[i] = points[i] - clip.pos.XY(); + + if (d[0].dot(d[1].Rotated90CW()) < 0) + { + if (IsCloseToLine(clip.center, points[1], points[0], clip.movedist) != EClose::Outside) + addClipLine(clip, points[1] + offset.Rotated90CCW(), points[0] + offset, objtype); + } + else if (d[2].dot(d[3].Rotated90CW()) < 0) + { + if (IsCloseToLine(clip.center, points[3], points[2], clip.movedist) != EClose::Outside) + addClipLine(clip, points[3] + offset.Rotated90CW(), points[2] - offset, objtype); + } + + if (d[1].dot(d[2].Rotated90CW()) < 0) + { + if (IsCloseToLine(clip.center, points[2], points[1], clip.movedist) != EClose::Outside) + addClipLine(clip, points[2] - offset, points[1] + offset.Rotated90CCW(), objtype); + } + else if (d[3].dot(d[0].Rotated90CW()) < 0) + { + if (IsCloseToLine(clip.center, points[0], points[3], clip.movedist) != EClose::Outside) + addClipLine(clip, points[0] + offset, points[3] + offset.Rotated90CW(), objtype); + } + } + return true; +} + +//========================================================================== +// +// +// +//========================================================================== + int FindBestSector(const DVector3& pos) { int bestnum = -1; diff --git a/source/core/gamefuncs.h b/source/core/gamefuncs.h index f332e8b98..cd8768d6e 100644 --- a/source/core/gamefuncs.h +++ b/source/core/gamefuncs.h @@ -261,6 +261,7 @@ void processClipWalls(MoveClipper& clip, sectortype* sec); void processClipFaceSprite(MoveClipper& clip, DCoreActor* actor); void processClipWallSprite(MoveClipper& clip, DCoreActor* actor); +bool processClipFloorSprite(MoveClipper& clip, DCoreActor* actor); int FindBestSector(const DVector3& pos);