From f6ad998e6b83dbbbb889146fda7c48be4a19bad3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 23 Oct 2022 13:23:09 +0200 Subject: [PATCH] - float version of face sprite collector. --- source/build/src/clip.cpp | 19 ++-------- source/common/utility/geometry.h | 13 ++++++- source/core/gamefuncs.cpp | 60 +++++++++++++++++++++++--------- source/core/gamefuncs.h | 3 +- 4 files changed, 59 insertions(+), 36 deletions(-) diff --git a/source/build/src/clip.cpp b/source/build/src/clip.cpp index d83716fcf..22d178a0e 100644 --- a/source/build/src/clip.cpp +++ b/source/build/src/clip.cpp @@ -250,7 +250,7 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect, clip.pos = { pos->X * inttoworld, pos->Y * inttoworld, pos->Z * zinttoworld }; ////////// Walls ////////// - addWallsToClipList(clip, §or[dasect]); + processClipWalls(clip, §or[dasect]); if (clipmove_warned & 1) Printf("clipsectnum >= MAXCLIPSECTORS!\n"); @@ -280,22 +280,7 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect, switch (cstat & (CSTAT_SPRITE_ALIGNMENT_MASK)) { case CSTAT_SPRITE_ALIGNMENT_FACING: - if (p1.X >= clipMin.X && p1.X <= clipMax.X && p1.Y >= clipMin.Y && p1.Y <= clipMax.Y) - { - double height_, daz_ = actor->spr.pos.Z + actor->GetOffsetAndHeight(height_); - int height = int(height_ * zworldtoint), daz = int(daz_ * zworldtoint); - - if (pos->Z > daz-height-flordist && pos->Z < daz+ceildist) - { - int cd = int(actor->clipdist * worldtoint); - int32_t bsz = cd + walldist; - if (diff.X < 0) bsz = -bsz; - addclipline(p1.X-bsz, p1.Y-bsz, p1.X-bsz, p1.Y+bsz, obj, false); - bsz = cd + walldist; - if (diff.Y < 0) bsz = -bsz; - addclipline(p1.X+bsz, p1.Y-bsz, p1.X-bsz, p1.Y-bsz, obj, false); - } - } + processClipFaceSprites(clip, actor); break; case CSTAT_SPRITE_ALIGNMENT_WALL: diff --git a/source/common/utility/geometry.h b/source/common/utility/geometry.h index c3fb1b85f..aa4a5ccc4 100644 --- a/source/common/utility/geometry.h +++ b/source/common/utility/geometry.h @@ -221,7 +221,7 @@ inline int BoxOnLineSide(const DVector2& boxtl, const DVector2& boxbr, const DVe //========================================================================== // -// BoxInRange +// BoxInRange. Two variants becaise they cannot be that easily merged. // //========================================================================== @@ -240,3 +240,14 @@ inline bool BoxInRange2(const DVector2& boxtl, const DVector2& boxbr, const DVec boxtl.Y <= max(start.Y, end.Y) && boxbr.Y >= min(start.Y, end.Y); } + +//========================================================================== +// +// +// +//========================================================================== + +inline bool PointInRect(const DVector2& pt, const DVector2& min, const DVector2& max) +{ + return pt.X >= min.X && pt.X <= max.X && pt.Y >= min.Y && pt.Y <= max.Y; +} diff --git a/source/core/gamefuncs.cpp b/source/core/gamefuncs.cpp index d43e262ff..e49207431 100644 --- a/source/core/gamefuncs.cpp +++ b/source/core/gamefuncs.cpp @@ -1288,6 +1288,21 @@ static int checkClipWall(const MoveClipper& clip, walltype* wal) } } +//========================================================================== +// +// +// +//========================================================================== + +static void addPointToClipList(MoveClipper& clip, const DVector2& pos, double radius, CollisionBase& objtype) +{ + double waldist = (clip.moveDelta.X < 0)? radius : -radius; + addClipLine(clip, pos + DVector2(waldist, waldist), pos + DVector2(waldist, -waldist), objtype); + + waldist = (clip.moveDelta.Y < 0) ? radius : -radius; + addClipLine(clip, pos + DVector2(-waldist, waldist), pos + DVector2(waldist, waldist), objtype); +} + //========================================================================== // // To produce reproducable results, this of course needs to add the exact same @@ -1305,24 +1320,11 @@ static void addWallToClipSet(MoveClipper& clip, walltype* wal) 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); + addPointToClipList(clip, startpt, clip.walldist, objtype); + addPointToClipList(clip, endpt, clip.walldist, objtype); // this is actually a very poor concept of 'distance' being used... - distv1 = { clip.walldist, clip.walldist }; + DVector2 distv1(clip.walldist, clip.walldist); if (wal->delta().Y > 0) distv1.X = -distv1.X; if (wal->delta().X < 0) distv1.Y = -distv1.Y; @@ -1346,7 +1348,7 @@ static void addWallToClipSet(MoveClipper& clip, walltype* wal) // //========================================================================== -void addWallsToClipList(MoveClipper& clip, sectortype* sec) +void processClipWalls(MoveClipper& clip, sectortype* sec) { for(auto& wal : wallsofsector(sec)) { @@ -1369,6 +1371,30 @@ void addWallsToClipList(MoveClipper& clip, sectortype* sec) // //========================================================================== +void processClipFaceSprites(MoveClipper& clip, DCoreActor* actor) +{ + auto spos = actor->spr.pos; + if (!PointInRect(spos.XY(), clip.rect.min, clip.rect.max)) return; // are we outside this sprite's bounding box? + + double height, z = spos.Z + actor->GetOffsetAndHeight(height); + + if (clip.pos.Z <= z - height - clip.floordist) return; // are we above the sprite? + if (clip.pos.Z >= z + clip.ceilingdist) return; // are we below the sprite? + + // if we get here we have hit this sprite so add its box to the clip list. + + CollisionBase objtype; + objtype.setSprite(actor); + + addPointToClipList(clip, spos.XY(), actor->clipdist + clip.walldist, objtype); +} + +//========================================================================== +// +// +// +//========================================================================== + int FindBestSector(const DVector3& pos) { int bestnum = 1; diff --git a/source/core/gamefuncs.h b/source/core/gamefuncs.h index e47908207..1f99ca120 100644 --- a/source/core/gamefuncs.h +++ b/source/core/gamefuncs.h @@ -288,8 +288,9 @@ struct MoveClipper 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); +void processClipWalls(MoveClipper& clip, sectortype* sec); +void processClipFaceSprites(MoveClipper& clip, DCoreActor* actor); int FindBestSector(const DVector3& pos);