mirror of
https://github.com/ZDoom/Raze.git
synced 2025-04-26 09:40:57 +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];
|
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;
|
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,
|
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
|
// 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;
|
return (int)IsCloseToLine(DVector2(x * inttoworld, y * inttoworld), DVector2(x1 * inttoworld, y1 * inttoworld), DVector2(x2 * inttoworld, y2 * inttoworld), walldist * inttoworld);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t clipmove_warned;
|
static int32_t clipmove_warned;
|
||||||
|
@ -896,7 +840,7 @@ int pushmove_(vec3_t *const vect, int *const sectnum,
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=startwall, wal=&wall[startwall]; i!=endwall; i+=dir, wal+=dir)
|
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;
|
int j = 0;
|
||||||
if (wal->nextsector < 0 || wal->cstat & EWallFlags::FromInt(dawalclipmask)) j = 1;
|
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;
|
vect->X = (vect->X) + dx; vect->Y = (vect->Y) + dy;
|
||||||
bad2--; if (bad2 == 0) break;
|
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;
|
bad = -1;
|
||||||
k--; if (k <= 0) return bad;
|
k--; if (k <= 0) return bad;
|
||||||
clipupdatesector(vect->vec2, sectnum, walldist);
|
clipupdatesector(vect->vec2, sectnum, walldist);
|
||||||
|
@ -1451,4 +1395,3 @@ int hitscan(const vec3_t& start, const sectortype* startsect, const vec3_t& dire
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -393,6 +393,48 @@ void GetFlatSpritePosition(const tspritetype* spr, const DVector2& pos, DVector2
|
||||||
TGetFlatSpritePosition(spr, pos, out, outz, tspriteGetSlope(spr), render);
|
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.
|
// 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 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(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);
|
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();
|
void checkRotatedWalls();
|
||||||
bool sectorsConnected(int sect1, int sect2);
|
bool sectorsConnected(int sect1, int sect2);
|
||||||
void dragpoint(walltype* wal, int newx, int newy);
|
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;
|
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
|
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)
|
inline double WallStartX(int wallnum)
|
||||||
{
|
{
|
||||||
return wall[wallnum].pos.X;
|
return wall[wallnum].pos.X;
|
||||||
|
|
|
@ -232,8 +232,8 @@ static int OutlineToFloat(Outline& outl, FOutline& polygon)
|
||||||
count += outl[i].Size();
|
count += outl[i].Size();
|
||||||
for (unsigned j = 0; j < outl[i].Size(); j++)
|
for (unsigned j = 0; j < outl[i].Size(); j++)
|
||||||
{
|
{
|
||||||
float X = RenderX(outl[i][j].X);
|
float X = (outl[i][j].X) * inttoworld;
|
||||||
float Y = RenderY(outl[i][j].Y);
|
float Y = (outl[i][j].Y) * -inttoworld;
|
||||||
if (fabs(X) > 32768.f || fabs(Y) > 32768.f)
|
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.
|
// 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;
|
return -1;
|
||||||
}
|
}
|
||||||
polygon[i][j] = { X, Y };
|
polygon[i][j] = { X, Y };
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3537,7 +3537,7 @@ void handle_se11(DDukeActor *actor)
|
||||||
DukeStatIterator it(STAT_ACTOR);
|
DukeStatIterator it(STAT_ACTOR);
|
||||||
while (auto ac = it.Next())
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3553,7 +3553,7 @@ void handle_se11(DDukeActor *actor)
|
||||||
DukeStatIterator it(STAT_PLAYER);
|
DukeStatIterator it(STAT_PLAYER);
|
||||||
while (auto ac = it.Next())
|
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[5] = 8; // Delay
|
||||||
actor->temp_data[2] -= k;
|
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();
|
auto pSector = pActor->sector();
|
||||||
int z = pActor->int_pos().Z;
|
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()))
|
if (!search.Check(wal.nextSector()))
|
||||||
{
|
{
|
||||||
vec2_t pos = { x, y };
|
if (IsCloseToWall(pActor->spr.pos, &wal, walldist) != EClose::Outside)
|
||||||
if (clipinsidebox(pos, wallnum(&wal), walldist))
|
|
||||||
{
|
{
|
||||||
search.Add(wal.nextSector());
|
search.Add(wal.nextSector());
|
||||||
}
|
}
|
||||||
|
@ -470,7 +469,7 @@ Collision movespritez(DExhumedActor* pActor, int z, int height, int, int clipdis
|
||||||
|
|
||||||
if (pActor->spr.statnum == 100)
|
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;
|
return nRet;
|
||||||
|
|
|
@ -13840,36 +13840,9 @@ int InitSerpSlash(DSWActor* actor)
|
||||||
|
|
||||||
bool WallSpriteInsideSprite(DSWActor* wactor, DSWActor* actor)
|
bool WallSpriteInsideSprite(DSWActor* wactor, DSWActor* actor)
|
||||||
{
|
{
|
||||||
int x1, y1, x2, y2;
|
DVector2 out[2];
|
||||||
int xoff;
|
GetWallSpritePosition(&wactor->spr, wactor->spr.pos, out);
|
||||||
int dax, day;
|
return IsCloseToLine(actor->spr.pos.XY(), out[0], out[1], (((int) actor->spr.clipdist) << 2) * inttoworld) != EClose::Outside;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue