diff --git a/source/build/src/clip.cpp b/source/build/src/clip.cpp index 1e9397214..a4bda1909 100644 --- a/source/build/src/clip.cpp +++ b/source/build/src/clip.cpp @@ -262,7 +262,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"); @@ -292,22 +292,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 6e22cb031..805881965 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 3272a106b..350192017 100644 --- a/source/core/gamefuncs.cpp +++ b/source/core/gamefuncs.cpp @@ -1256,6 +1256,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 @@ -1273,24 +1288,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; @@ -1314,7 +1316,7 @@ static void addWallToClipSet(MoveClipper& clip, walltype* wal) // //========================================================================== -void addWallsToClipList(MoveClipper& clip, sectortype* sec) +void processClipWalls(MoveClipper& clip, sectortype* sec) { for(auto& wal : sec->walls) { @@ -1337,6 +1339,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 e92306288..3c64c1713 100644 --- a/source/core/gamefuncs.h +++ b/source/core/gamefuncs.h @@ -255,9 +255,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);