mirror of
https://github.com/ZDoom/Raze.git
synced 2025-01-18 14:41:55 +00:00
- redid clipinsidebox* functions.
* Completely rewritten to be less obtuse. * Consolidated the two variants. * Renamed to be clearer about what they do.
This commit is contained in:
parent
b9d0c9d6ba
commit
3a9f9988f4
8 changed files with 67 additions and 121 deletions
|
@ -21,9 +21,6 @@ typedef struct
|
|||
|
||||
extern int clipsectorlist[MAXCLIPSECTORS];
|
||||
|
||||
int clipinsidebox(const vec2_t &vect, int wallnum, int walldist);
|
||||
int clipinsideboxline(int x, int y, int x1, int y1, int x2, int y2, int walldist);
|
||||
|
||||
struct CollisionBase;
|
||||
|
||||
CollisionBase clipmove_(vec3_t *const pos, int *const sectnum, int32_t xvect, int32_t yvect, int32_t const walldist, int32_t const ceildist,
|
||||
|
|
|
@ -59,68 +59,12 @@ static inline void get_floorspr_points(DCoreActor *spr, int32_t px, int32_t py,
|
|||
|
||||
}
|
||||
|
||||
//
|
||||
// clipinsidebox
|
||||
//
|
||||
int clipinsidebox(const vec2_t &vect, int wallnum, int walldist)
|
||||
{
|
||||
int const r = walldist << 1;
|
||||
|
||||
auto const wal1 = &wall[wallnum];
|
||||
auto const wal2 = wal1->point2Wall();
|
||||
|
||||
vec2_t const v1 = { wal1->wall_int_pos().X + walldist - vect.X, wal1->wall_int_pos().Y + walldist - vect.Y };
|
||||
vec2_t v2 = { wal2->wall_int_pos().X + walldist - vect.X, wal2->wall_int_pos().Y + walldist - vect.Y };
|
||||
|
||||
if (((v1.X < 0) && (v2.X < 0)) || ((v1.Y < 0) && (v2.Y < 0)) || ((v1.X >= r) && (v2.X >= r)) || ((v1.Y >= r) && (v2.Y >= r)))
|
||||
return 0;
|
||||
|
||||
v2.X -= v1.X; v2.Y -= v1.Y;
|
||||
|
||||
if (v2.X * (walldist - v1.Y) >= v2.Y * (walldist - v1.X)) // Front
|
||||
{
|
||||
v2.X *= ((v2.X > 0) ? (0 - v1.Y) : (r - v1.Y));
|
||||
v2.Y *= ((v2.Y > 0) ? (r - v1.X) : (0 - v1.X));
|
||||
return v2.X < v2.Y;
|
||||
}
|
||||
|
||||
v2.X *= ((v2.X > 0) ? (r - v1.Y) : (0 - v1.Y));
|
||||
v2.Y *= ((v2.Y > 0) ? (0 - v1.X) : (r - v1.X));
|
||||
return (v2.X >= v2.Y) << 1;
|
||||
}
|
||||
|
||||
//
|
||||
// clipinsideboxline
|
||||
//
|
||||
int clipinsideboxline(int x, int y, int x1, int y1, int x2, int y2, int walldist)
|
||||
static int clipinsideboxline(int x, int y, int x1, int y1, int x2, int y2, int walldist)
|
||||
{
|
||||
int const r = walldist << 1;
|
||||
|
||||
x1 += walldist - x;
|
||||
x2 += walldist - x;
|
||||
|
||||
if (((x1 < 0) && (x2 < 0)) || ((x1 >= r) && (x2 >= r)))
|
||||
return 0;
|
||||
|
||||
y1 += walldist - y;
|
||||
y2 += walldist - y;
|
||||
|
||||
if (((y1 < 0) && (y2 < 0)) || ((y1 >= r) && (y2 >= r)))
|
||||
return 0;
|
||||
|
||||
x2 -= x1;
|
||||
y2 -= y1;
|
||||
|
||||
if (x2 * (walldist - y1) >= y2 * (walldist - x1)) // Front
|
||||
{
|
||||
x2 *= ((x2 > 0) ? (0 - y1) : (r - y1));
|
||||
y2 *= ((y2 > 0) ? (r - x1) : (0 - x1));
|
||||
return x2 < y2;
|
||||
}
|
||||
|
||||
x2 *= ((x2 > 0) ? (r - y1) : (0 - y1));
|
||||
y2 *= ((y2 > 0) ? (0 - x1) : (r - x1));
|
||||
return (x2 >= y2) << 1;
|
||||
return (int)IsCloseToLine(DVector2(x * inttoworld, y * inttoworld), DVector2(x1 * inttoworld, y1 * inttoworld), DVector2(x2 * inttoworld, y2 * inttoworld), walldist * inttoworld);
|
||||
}
|
||||
|
||||
static int32_t clipmove_warned;
|
||||
|
@ -896,7 +840,7 @@ int pushmove_(vec3_t *const vect, int *const sectnum,
|
|||
int i;
|
||||
|
||||
for (i=startwall, wal=&wall[startwall]; i!=endwall; i+=dir, wal+=dir)
|
||||
if (clipinsidebox(vect->vec2, i, walldist-4) == 1)
|
||||
if (IsCloseToWall(DVector2(vect->X * inttoworld, vect->Y * inttoworld), &wall[i], (walldist-4) * inttoworld) == EClose::InFront)
|
||||
{
|
||||
int j = 0;
|
||||
if (wal->nextsector < 0 || wal->cstat & EWallFlags::FromInt(dawalclipmask)) j = 1;
|
||||
|
@ -918,7 +862,7 @@ int pushmove_(vec3_t *const vect, int *const sectnum,
|
|||
{
|
||||
vect->X = (vect->X) + dx; vect->Y = (vect->Y) + dy;
|
||||
bad2--; if (bad2 == 0) break;
|
||||
} while (clipinsidebox(vect->vec2, i, walldist-4) != 0);
|
||||
} while (IsCloseToWall(DVector2(vect->X * inttoworld, vect->Y * inttoworld), &wall[i], (walldist - 4) * inttoworld) != EClose::Outside);
|
||||
bad = -1;
|
||||
k--; if (k <= 0) return bad;
|
||||
clipupdatesector(vect->vec2, sectnum, walldist);
|
||||
|
@ -1451,4 +1395,3 @@ int hitscan(const vec3_t& start, const sectortype* startsect, const vec3_t& dire
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -393,6 +393,48 @@ void GetFlatSpritePosition(const tspritetype* spr, const DVector2& pos, DVector2
|
|||
TGetFlatSpritePosition(spr, pos, out, outz, tspriteGetSlope(spr), render);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// checks if the given point is sufficiently close to the given line segment.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
EClose IsCloseToLine(const DVector2& point, const DVector2& start, const DVector2& end, double maxdist)
|
||||
{
|
||||
auto const v1 = start - point;
|
||||
auto const v2 = end - point;
|
||||
|
||||
// trivially outside the box.
|
||||
if (
|
||||
((v1.X < -maxdist) && (v2.X < -maxdist)) || // fully to the left
|
||||
((v1.Y < -maxdist) && (v2.Y < -maxdist)) || // fully below
|
||||
((v1.X >= maxdist) && (v2.X >= maxdist)) || // fully to the right
|
||||
((v1.Y >= maxdist) && (v2.Y >= maxdist))) // fully above
|
||||
return EClose::Outside;
|
||||
|
||||
auto waldelta = end - start;
|
||||
|
||||
if (waldelta.X * v1.Y <= waldelta.Y * v1.X)
|
||||
{
|
||||
// is it in front?
|
||||
waldelta.X *= waldelta.X > 0 ? v1.Y + maxdist : v1.Y - maxdist;
|
||||
waldelta.Y *= waldelta.Y > 0 ? v1.X - maxdist : v1.X + maxdist;
|
||||
return waldelta.X > waldelta.Y ? EClose::InFront : EClose::Outside;
|
||||
}
|
||||
else
|
||||
{
|
||||
// or behind?
|
||||
waldelta.X *= waldelta.X > 0 ? v1.Y - maxdist : v1.Y + maxdist;
|
||||
waldelta.Y *= waldelta.Y > 0 ? v1.X + maxdist : v1.X - maxdist;
|
||||
return (waldelta.X <= waldelta.Y) ? EClose::Behind : EClose::Outside;
|
||||
}
|
||||
}
|
||||
|
||||
EClose IsCloseToWall(const DVector2& point, walltype* wal, double maxdist)
|
||||
{
|
||||
return IsCloseToLine(point, wal->pos, wal->point2Wall()->pos, maxdist);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Check if some walls are set to use rotated textures.
|
||||
|
|
|
@ -268,6 +268,16 @@ void setWallSectors();
|
|||
void GetWallSpritePosition(const spritetypebase* spr, const DVector2& pos, DVector2* out, bool render = false);
|
||||
void GetFlatSpritePosition(DCoreActor* spr, const DVector2& pos, DVector2* out, bool render = false);
|
||||
void GetFlatSpritePosition(const tspritetype* spr, const DVector2& pos, DVector2* out, double* outz, bool render = false);
|
||||
|
||||
enum class EClose
|
||||
{
|
||||
Outside,
|
||||
InFront,
|
||||
Behind
|
||||
};
|
||||
EClose IsCloseToLine(const DVector2& vect, const DVector2& start, const DVector2& end, double walldist);
|
||||
EClose IsCloseToWall(const DVector2& vect, walltype* wal, double walldist);
|
||||
|
||||
void checkRotatedWalls();
|
||||
bool sectorsConnected(int sect1, int sect2);
|
||||
void dragpoint(walltype* wal, int newx, int newy);
|
||||
|
@ -288,11 +298,6 @@ inline double getflorzofslopeptrf(const sectortype* sec, double dax, double day)
|
|||
{
|
||||
return getflorzofslopeptr(sec, dax * worldtoint, day * worldtoint) * zinttoworld;
|
||||
}
|
||||
[[deprecated]]
|
||||
inline void getzsofslopeptrf(const sectortype* sec, double dax, double day, double* ceilz, double* florz)
|
||||
{
|
||||
getzsofslopeptr(sec, dax, day, ceilz, florz);
|
||||
}
|
||||
|
||||
|
||||
enum EFindNextSector
|
||||
|
@ -314,19 +319,6 @@ sectortype* nextsectorneighborzptr(sectortype* sectp, int startz, int flags);
|
|||
|
||||
|
||||
|
||||
// y is negated so that the orientation is the same as in GZDoom, in order to use its utilities.
|
||||
// The render code should NOT use Build coordinates for anything!
|
||||
|
||||
inline double RenderX(int x)
|
||||
{
|
||||
return x * (1 / 16.);
|
||||
}
|
||||
|
||||
inline double RenderY(int y)
|
||||
{
|
||||
return y * (1 / -16.);
|
||||
}
|
||||
|
||||
inline double WallStartX(int wallnum)
|
||||
{
|
||||
return wall[wallnum].pos.X;
|
||||
|
|
|
@ -232,8 +232,8 @@ static int OutlineToFloat(Outline& outl, FOutline& polygon)
|
|||
count += outl[i].Size();
|
||||
for (unsigned j = 0; j < outl[i].Size(); j++)
|
||||
{
|
||||
float X = RenderX(outl[i][j].X);
|
||||
float Y = RenderY(outl[i][j].Y);
|
||||
float X = (outl[i][j].X) * inttoworld;
|
||||
float Y = (outl[i][j].Y) * -inttoworld;
|
||||
if (fabs(X) > 32768.f || fabs(Y) > 32768.f)
|
||||
{
|
||||
// If we get here there's some fuckery going around with the coordinates. Let's better abort and wait for things to realign.
|
||||
|
@ -241,8 +241,8 @@ static int OutlineToFloat(Outline& outl, FOutline& polygon)
|
|||
return -1;
|
||||
}
|
||||
polygon[i][j] = { X, Y };
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
|
|
@ -3537,7 +3537,7 @@ void handle_se11(DDukeActor *actor)
|
|||
DukeStatIterator it(STAT_ACTOR);
|
||||
while (auto ac = it.Next())
|
||||
{
|
||||
if (ac->spr.extra > 0 && badguy(ac) && clipinsidebox(ac->int_pos().vec2, wallnum(&wal), 256) == 1)
|
||||
if (ac->spr.extra > 0 && badguy(ac) && IsCloseToWall(ac->spr.pos.XY(), &wal, 16) == EClose::InFront)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -3553,7 +3553,7 @@ void handle_se11(DDukeActor *actor)
|
|||
DukeStatIterator it(STAT_PLAYER);
|
||||
while (auto ac = it.Next())
|
||||
{
|
||||
if (ac->GetOwner() && clipinsidebox(ac->int_pos().vec2, wallnum(&wal), 144) == 1)
|
||||
if (ac->GetOwner() && IsCloseToWall(ac->spr.pos.XY(), &wal, 9) == EClose::InFront)
|
||||
{
|
||||
actor->temp_data[5] = 8; // Delay
|
||||
actor->temp_data[2] -= k;
|
||||
|
|
|
@ -237,7 +237,7 @@ void clipwall()
|
|||
|
||||
}
|
||||
|
||||
int BelowNear(DExhumedActor* pActor, int x, int y, int walldist)
|
||||
int BelowNear(DExhumedActor* pActor, double walldist)
|
||||
{
|
||||
auto pSector = pActor->sector();
|
||||
int z = pActor->int_pos().Z;
|
||||
|
@ -263,8 +263,7 @@ int BelowNear(DExhumedActor* pActor, int x, int y, int walldist)
|
|||
{
|
||||
if (!search.Check(wal.nextSector()))
|
||||
{
|
||||
vec2_t pos = { x, y };
|
||||
if (clipinsidebox(pos, wallnum(&wal), walldist))
|
||||
if (IsCloseToWall(pActor->spr.pos, &wal, walldist) != EClose::Outside)
|
||||
{
|
||||
search.Add(wal.nextSector());
|
||||
}
|
||||
|
@ -470,7 +469,7 @@ Collision movespritez(DExhumedActor* pActor, int z, int height, int, int clipdis
|
|||
|
||||
if (pActor->spr.statnum == 100)
|
||||
{
|
||||
nRet.exbits |= BelowNear(pActor, pActor->int_pos().X, pActor->int_pos().Y, clipdist + (clipdist / 2));
|
||||
nRet.exbits |= BelowNear(pActor, clipdist * (inttoworld * 1.5));
|
||||
}
|
||||
|
||||
return nRet;
|
||||
|
|
|
@ -13840,36 +13840,9 @@ int InitSerpSlash(DSWActor* actor)
|
|||
|
||||
bool WallSpriteInsideSprite(DSWActor* wactor, DSWActor* actor)
|
||||
{
|
||||
int x1, y1, x2, y2;
|
||||
int xoff;
|
||||
int dax, day;
|
||||
int xsiz, mid_dist;
|
||||
|
||||
x1 = wactor->int_pos().X;
|
||||
y1 = wactor->int_pos().Y;
|
||||
|
||||
xoff = (int) tileLeftOffset(wactor->spr.picnum) + (int) wactor->spr.xoffset;
|
||||
|
||||
if ((wactor->spr.cstat & CSTAT_SPRITE_XFLIP))
|
||||
xoff = -xoff;
|
||||
|
||||
// x delta
|
||||
dax = bsin(wactor->int_ang()) * wactor->spr.xrepeat;
|
||||
// y delta
|
||||
day = -bcos(wactor->int_ang()) * wactor->spr.xrepeat;
|
||||
|
||||
xsiz = tileWidth(wactor->spr.picnum);
|
||||
mid_dist = (xsiz >> 1) + xoff;
|
||||
|
||||
// starting from the center find the first point
|
||||
x1 -= MulScale(dax, mid_dist, 16);
|
||||
// starting from the first point find the end point
|
||||
x2 = x1 + MulScale(dax, xsiz, 16);
|
||||
|
||||
y1 -= MulScale(day, mid_dist, 16);
|
||||
y2 = y1 + MulScale(day, xsiz, 16);
|
||||
|
||||
return !!clipinsideboxline(actor->int_pos().X, actor->int_pos().Y, x1, y1, x2, y2, ((int) actor->spr.clipdist) << 2);
|
||||
DVector2 out[2];
|
||||
GetWallSpritePosition(&wactor->spr, wactor->spr.pos, out);
|
||||
return IsCloseToLine(actor->spr.pos.XY(), out[0], out[1], (((int) actor->spr.clipdist) << 2) * inttoworld) != EClose::Outside;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue