mirror of
https://github.com/DrBeef/Raze.git
synced 2025-01-31 13:10:39 +00:00
- further hitscan overhaul.
* added floating point sprite intersect handlers for all sprite types. Hopefully this code is more understandable than Build's original variant. * cleaned up intersectSprite a bit and moved the geometry math into the utility header. * made some minor corrections to neartag. * moved SW's testpointinquad to the backend because it was useful here.
This commit is contained in:
parent
6ca42dc08c
commit
116ba340b2
7 changed files with 182 additions and 154 deletions
|
@ -238,13 +238,6 @@ static inline int64_t compat_maybe_truncate_to_int32(int64_t val)
|
|||
return enginecompatibility_mode != ENGINECOMPATIBILITY_NONE ? (int32_t)val : val;
|
||||
}
|
||||
|
||||
extern int32_t rintersect(int32_t x1, int32_t y1, int32_t z1,
|
||||
int32_t vx_, int32_t vy_, int32_t vz,
|
||||
int32_t x3, int32_t y3, int32_t x4, int32_t y4,
|
||||
int32_t *intx, int32_t *inty, int32_t *intz);
|
||||
|
||||
|
||||
|
||||
void updateModelInterpolation();
|
||||
|
||||
#endif // build_h_
|
||||
|
|
|
@ -1167,6 +1167,7 @@ int hitscan(const vec3_t& start, const sectortype* startsect, const vec3_t& dire
|
|||
int const vx = direction.X, vy = direction.Y, vz = direction.Z;
|
||||
int32_t x1, y1=0, z1=0, x2, y2, intx, inty, intz;
|
||||
int32_t i, k, daz;
|
||||
double hitfactor = DBL_MAX;
|
||||
|
||||
const int32_t dawalclipmask = (cliptype&65535);
|
||||
const int32_t dasprclipmask = (cliptype >> 16);
|
||||
|
@ -1202,11 +1203,15 @@ int hitscan(const vec3_t& start, const sectortype* startsect, const vec3_t& dire
|
|||
< compat_maybe_truncate_to_int32((coord_t)(x2-sv->X)*(y1-sv->Y))) continue;
|
||||
if (rintersect(sv->X,sv->Y,sv->Z, vx,vy,vz, x1,y1, x2,y2, &intx,&inty,&intz) == -1) continue;
|
||||
|
||||
if (abs(intx-sv->X)+abs(inty-sv->Y) >= abs((hitinfo.int_hitpos().X)-sv->X)+abs((hitinfo.int_hitpos().Y)-sv->Y))
|
||||
continue;
|
||||
// temporary crutch
|
||||
DVector2 vec(vx, vy);
|
||||
DVector2 newvec(intx - sv->X, inty - sv->Y);
|
||||
double newfactor = newvec.Sum() / vec.Sum();
|
||||
if (newfactor >= hitfactor) continue;
|
||||
|
||||
if ((!wal->twoSided()) || (wal->cstat & EWallFlags::FromInt(dawalclipmask)))
|
||||
{
|
||||
hitfactor = newfactor;
|
||||
hit_set(&hitinfo, sec, wal, nullptr, intx, inty, intz);
|
||||
continue;
|
||||
}
|
||||
|
@ -1215,6 +1220,7 @@ int hitscan(const vec3_t& start, const sectortype* startsect, const vec3_t& dire
|
|||
int_getzsofslopeptr(nextsect,intx,inty,&daz,&daz2);
|
||||
if (intz <= daz || intz >= daz2)
|
||||
{
|
||||
hitfactor = newfactor;
|
||||
hit_set(&hitinfo, sec, wal, nullptr, intx, inty, intz);
|
||||
continue;
|
||||
}
|
||||
|
@ -1227,6 +1233,9 @@ int hitscan(const vec3_t& start, const sectortype* startsect, const vec3_t& dire
|
|||
if (dasprclipmask==0)
|
||||
continue;
|
||||
|
||||
DVector3 start(sv->X * inttoworld, sv->Y * inttoworld, sv->Z * zinttoworld);
|
||||
DVector3 vect(vx * inttoworld, vy * inttoworld, vz * zinttoworld);
|
||||
|
||||
TSectIterator<DCoreActor> it(sec);
|
||||
while (auto actor = it.Next())
|
||||
{
|
||||
|
@ -1238,121 +1247,31 @@ int hitscan(const vec3_t& start, const sectortype* startsect, const vec3_t& dire
|
|||
if ((cstat&dasprclipmask) == 0)
|
||||
continue;
|
||||
|
||||
x1 = actor->int_pos().X; y1 = actor->int_pos().Y; z1 = actor->int_pos().Z;
|
||||
DVector3 v;
|
||||
double hit = -1;
|
||||
// we pass hitfactor to the workers because it can shortcut their calculations a lot.
|
||||
switch (cstat&CSTAT_SPRITE_ALIGNMENT_MASK)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
auto v = hitinfo.hitpos;
|
||||
DVector3 start(sv->X * inttoworld, sv->Y * inttoworld, sv->Z * zinttoworld);
|
||||
DVector3 direction(vx * inttoworld, vy * inttoworld, vz * zinttoworld);
|
||||
if (intersectSprite(actor, start, direction, v, 0))
|
||||
{
|
||||
if ((v.XY() - start.XY()).Sum() < (hitinfo.hitpos.XY() - start.XY()).Sum())
|
||||
hit_set(&hitinfo, sec, nullptr, actor, v.X * worldtoint, v.Y * worldtoint, v.Z * zworldtoint);
|
||||
}
|
||||
|
||||
case CSTAT_SPRITE_ALIGNMENT_FACING:
|
||||
hit = intersectSprite(actor, start, vect, v, hitfactor);
|
||||
break;
|
||||
}
|
||||
|
||||
case CSTAT_SPRITE_ALIGNMENT_WALL:
|
||||
{
|
||||
int32_t ucoefup16;
|
||||
int32_t tilenum = actor->spr.picnum;
|
||||
|
||||
get_wallspr_points(actor, &x1, &x2, &y1, &y2);
|
||||
|
||||
if ((cstat & CSTAT_SPRITE_ONE_SIDE) != 0) //back side of 1-way sprite
|
||||
if (compat_maybe_truncate_to_int32((coord_t)(x1-sv->X)*(y2-sv->Y))
|
||||
< compat_maybe_truncate_to_int32((coord_t)(x2-sv->X)*(y1-sv->Y))) continue;
|
||||
|
||||
ucoefup16 = rintersect(sv->X,sv->Y,sv->Z,vx,vy,vz,x1,y1,x2,y2,&intx,&inty,&intz);
|
||||
if (ucoefup16 == -1) continue;
|
||||
|
||||
if (abs(intx-sv->X)+abs(inty-sv->Y) > abs((hitinfo.int_hitpos().X)-sv->X)+abs((hitinfo.int_hitpos().Y)-sv->Y))
|
||||
continue;
|
||||
|
||||
daz = actor->int_pos().Z + actor->GetOffsetAndHeight(k);
|
||||
if (intz > daz-k && intz < daz)
|
||||
{
|
||||
if (picanm[tilenum].sf&PICANM_TEXHITSCAN_BIT)
|
||||
{
|
||||
tileUpdatePicnum(&tilenum);
|
||||
|
||||
if (tileLoad(tilenum))
|
||||
{
|
||||
// daz-intz > 0 && daz-intz < k
|
||||
int32_t xtex = MulScale(ucoefup16, tileWidth(tilenum), 16);
|
||||
int32_t vcoefup16 = 65536-DivScale(daz-intz, k, 16);
|
||||
int32_t ytex = MulScale(vcoefup16, tileHeight(tilenum), 16);
|
||||
|
||||
auto texel = (tilePtr(tilenum) + tileHeight(tilenum)*xtex + ytex);
|
||||
if (*texel == TRANSPARENT_INDEX)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
hit_set(&hitinfo, sec, nullptr, actor, intx, inty, intz);
|
||||
}
|
||||
hit = intersectWallSprite(actor, start, vect, v, hitfactor, (picanm[actor->spr.picnum].sf & PICANM_TEXHITSCAN_BIT));
|
||||
break;
|
||||
}
|
||||
|
||||
case CSTAT_SPRITE_ALIGNMENT_FLOOR:
|
||||
{
|
||||
int32_t x3, y3, x4, y4;
|
||||
intz = z1;
|
||||
|
||||
if (vz == 0 || ((intz-sv->Z)^vz) < 0) continue;
|
||||
|
||||
if ((cstat & CSTAT_SPRITE_ONE_SIDE) != 0)
|
||||
if ((sv->Z > intz) == ((cstat & CSTAT_SPRITE_YFLIP)==0)) continue;
|
||||
|
||||
// avoid overflow errors by using 64 bit math.
|
||||
intx = int(sv->X + (int64_t(intz) - sv->Z) * vx / vz);
|
||||
inty = int(sv->Y + (int64_t(intz) - sv->Z) * vy / vz);
|
||||
|
||||
if (abs(intx-sv->X)+abs(inty-sv->Y) > abs((hitinfo.int_hitpos().X)-sv->X)+abs((hitinfo.int_hitpos().Y)-sv->Y))
|
||||
continue;
|
||||
|
||||
get_floorspr_points(actor, intx, inty, &x1, &x2, &x3, &x4,
|
||||
&y1, &y2, &y3, &y4);
|
||||
|
||||
if (get_floorspr_clipyou({x1, y1}, {x2, y2}, {x3, y3}, {x4, y4}))
|
||||
hit_set(&hitinfo, sec, nullptr, actor, intx, inty, intz);
|
||||
|
||||
hit = intersectFloorSprite(actor, start, vect, v, hitfactor);
|
||||
break;
|
||||
}
|
||||
|
||||
case CSTAT_SPRITE_ALIGNMENT_SLOPE:
|
||||
{
|
||||
int32_t x3, y3, x4, y4;
|
||||
int32_t const heinum = spriteGetSlope(actor);
|
||||
int32_t const dax = (heinum * -bsin(actor->int_ang())) << 1;
|
||||
int32_t const day = (heinum * bcos(actor->int_ang())) << 1;
|
||||
int32_t const j = (vz << 8) - DMulScale(dax, vy, -day, vx, 15);
|
||||
if (j == 0) continue;
|
||||
if ((cstat & 64) != 0)
|
||||
if ((j < 0) == ((cstat & 8) == 0)) continue;
|
||||
int32_t dist2 = ((actor->int_pos().Z - sv->Z) << 8) + DMulScale(dax, sv->Y - actor->int_pos().Y, -day, sv->X - actor->int_pos().X, 15);
|
||||
if ((dist2 ^ j) < 0 || (abs(dist2) >> 1) >= abs(j)) continue;
|
||||
|
||||
dist2 = DivScale(dist2, j, 30);
|
||||
intx = sv->X + MulScale(vx, dist2, 30);
|
||||
inty = sv->Y + MulScale(vy, dist2, 30);
|
||||
intz = sv->Z + MulScale(vz, dist2, 30);
|
||||
|
||||
if (abs(intx - sv->X) + abs(inty - sv->Y) > abs((hitinfo.int_hitpos().X) - sv->X) + abs((hitinfo.int_hitpos().Y) - sv->Y))
|
||||
continue;
|
||||
|
||||
get_floorspr_points(actor, intx, inty, &x1, &x2, &x3, &x4,
|
||||
&y1, &y2, &y3, &y4);
|
||||
|
||||
if (get_floorspr_clipyou({ x1, y1 }, { x2, y2 }, { x3, y3 }, { x4, y4 }))
|
||||
hit_set(&hitinfo, sec, nullptr, actor, intx, inty, intz);
|
||||
|
||||
hit = intersectSlopeSprite(actor, start, vect, v, hitfactor);
|
||||
break;
|
||||
}
|
||||
|
||||
if (hit > 0)
|
||||
{
|
||||
hitfactor = hit;
|
||||
hitinfo.set(sec, nullptr, actor, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -259,6 +259,14 @@ struct HitInfoBase
|
|||
hitWall = nullptr;
|
||||
hitActor = nullptr;
|
||||
}
|
||||
|
||||
void set(sectortype* sect, walltype* wal, DCoreActor* actor, const DVector3& pos)
|
||||
{
|
||||
hitSector = sect;
|
||||
hitWall = wal;
|
||||
hitActor = actor;
|
||||
hitpos = pos;
|
||||
}
|
||||
|
||||
const vec3_t int_hitpos() const
|
||||
{
|
||||
|
|
|
@ -566,6 +566,21 @@ bool cansee(const DVector3& start, sectortype* sect1, const DVector3& end, secto
|
|||
return search.Check(sect2);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// taken out of SW.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
int testpointinquad(const DVector2& pt, const DVector2* quad)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
double dist = PointOnLineSide(pt.X, pt.Y, quad[i].X, quad[i].Y, quad[(i + 1) & 3].X - quad[i].X, quad[(i + 1) & 3].Y - quad[i].Y);
|
||||
if (dist > 0) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -573,36 +588,131 @@ bool cansee(const DVector3& start, sectortype* sect1, const DVector3& end, secto
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool intersectSprite(DCoreActor* actor, const DVector3& start, const DVector3& direction, DVector3& result, double displacement)
|
||||
double intersectSprite(DCoreActor* actor, const DVector3& start, const DVector3& direction, DVector3& result, double maxfactor)
|
||||
{
|
||||
auto end = start + direction;
|
||||
if (direction.isZero()) return false;
|
||||
|
||||
// use dot product to check if the sprite is behind us (or ourselves if the result is 0)
|
||||
auto dotprod = direction.XY().dot(actor->spr.pos.XY() - start.XY());
|
||||
if (dotprod <= 0) return false;
|
||||
|
||||
// get point on trace that is closest to the sprite
|
||||
double const length = direction.XY().LengthSquared();
|
||||
DVector3 point = start + direction * (dotprod / length);
|
||||
double factor = NearestPointOnLineFast(actor->spr.pos.X, actor->spr.pos.Y, start.X, start.Y, end.X, end.Y);
|
||||
if (factor < 0 || factor > maxfactor) return -1;
|
||||
|
||||
// This is somewhat smaller than the sprite's actual size, but that's how it was
|
||||
auto sprwidth = tileWidth(actor->spr.picnum) * actor->spr.xrepeat * (REPEAT_SCALE * 0.5) + displacement;
|
||||
auto sprwidth = tileWidth(actor->spr.picnum) * actor->spr.xrepeat * (REPEAT_SCALE * 0.5);
|
||||
auto point = start + direction * factor;
|
||||
|
||||
// Using proper distance here, Build originally used the sum of x- and y-distance
|
||||
if ((point.XY() - actor->spr.pos.XY()).LengthSquared() > sprwidth * sprwidth * 0.5) return false; // too far away
|
||||
if ((point.XY() - actor->spr.pos.XY()).LengthSquared() > sprwidth * sprwidth * 0.5) return -1; // too far away
|
||||
|
||||
double newz = point.Z;
|
||||
double siz, hitz = actor->spr.pos.Z + actor->GetOffsetAndHeight(siz);
|
||||
|
||||
double siz;
|
||||
double const hitz = actor->spr.pos.Z + actor->GetOffsetAndHeight(siz);
|
||||
if (point.Z < hitz - siz || point.Z > hitz)
|
||||
return -1;
|
||||
|
||||
if (newz < hitz - siz || newz > hitz)
|
||||
return 0;
|
||||
result = point;
|
||||
return factor;
|
||||
}
|
||||
|
||||
result.XY() = point;
|
||||
result.Z = newz;
|
||||
return 1;
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
double intersectWallSprite(DCoreActor* actor, const DVector3& start, const DVector3& direction, DVector3& result, double maxfactor, bool checktex)
|
||||
{
|
||||
DVector2 points[2];
|
||||
|
||||
GetWallSpritePosition(&actor->spr, actor->spr.pos, points, false);
|
||||
|
||||
points[1] -= points[0];
|
||||
if ((actor->spr.cstat & CSTAT_SPRITE_ONE_SIDE)) //check for back side of one way sprite
|
||||
{
|
||||
if (PointOnLineSide(start.X, start.Y, points[0].X, points[0].Y, points[1].X, points[1].Y) > 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
double factor2;
|
||||
double factor = InterceptLineSegments(start.X, start.Y, direction.X, direction.Y, points[0].X, points[0].Y, points[1].X, points[1].Y, &factor2);
|
||||
if (factor < 0 || factor > maxfactor || factor2 < 0 || factor2 > 1) return -1;
|
||||
|
||||
result = start + factor * direction;
|
||||
|
||||
double height, position = actor->spr.pos.Z + actor->GetOffsetAndHeight(height);
|
||||
if (result.Z <= position - height || result.Z >= position) return -1;
|
||||
|
||||
if (checktex)
|
||||
{
|
||||
int tilenum = actor->spr.picnum;
|
||||
tileUpdatePicnum(&tilenum);
|
||||
|
||||
if (tileLoad(tilenum))
|
||||
{
|
||||
double zfactor = 1. - (position - result.Z) / height;
|
||||
|
||||
// all other flags have been taken care of already by GetWallSpritePosition and GetOffsetAndHeight
|
||||
// - but we have to handle the flip flags here to fetch the correct texel.
|
||||
if (actor->spr.cstat & CSTAT_SPRITE_XFLIP) factor2 = 1 - factor2;
|
||||
if (actor->spr.cstat & CSTAT_SPRITE_YFLIP) zfactor = 1 - zfactor;
|
||||
|
||||
int xtex = int(factor2 * tileWidth(tilenum));
|
||||
int ytex = int(zfactor * tileHeight(tilenum));
|
||||
|
||||
auto texel = (tilePtr(tilenum) + tileHeight(tilenum) * xtex + ytex);
|
||||
if (*texel == TRANSPARENT_INDEX)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return factor;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
double intersectFloorSprite(DCoreActor* actor, const DVector3& start, const DVector3& direction, DVector3& result, double maxfactor)
|
||||
{
|
||||
if (actor->spr.cstat & CSTAT_SPRITE_ONE_SIDE)
|
||||
{
|
||||
if ((start.Z > actor->spr.pos.Z) == ((actor->spr.cstat & CSTAT_SPRITE_YFLIP) == 0)) return -1;
|
||||
}
|
||||
|
||||
DVector2 points[4];
|
||||
GetFlatSpritePosition(actor, actor->spr.pos, points, nullptr, false);
|
||||
double factor = (actor->spr.pos.Z - start.Z) / direction.Z;
|
||||
if (factor <= 0 || factor > maxfactor) return -1;
|
||||
result = start + factor * direction;
|
||||
if (!testpointinquad(result.XY(), points)) return -1;
|
||||
return factor;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
double intersectSlopeSprite(DCoreActor* actor, const DVector3& start, const DVector3& direction, DVector3& result, double maxfactor)
|
||||
{
|
||||
DVector2 points[4];
|
||||
double ptz[4];
|
||||
GetFlatSpritePosition(actor, actor->spr.pos, points, ptz, false);
|
||||
DVector3 pt1(points[0], ptz[0]);
|
||||
DVector3 pt2(points[1], ptz[1]);
|
||||
DVector3 pt3(points[2], ptz[2]);
|
||||
double factor = LinePlaneIntersect(start, direction, pt1, pt2 - pt1, pt3 - pt1);
|
||||
if (factor <= 0 || factor > maxfactor) return -1;
|
||||
result = start + factor * direction;
|
||||
|
||||
// we can only do this after calculating the actual intersection spot...
|
||||
if (actor->spr.cstat & CSTAT_SPRITE_ONE_SIDE)
|
||||
{
|
||||
double checkz = spriteGetZOfSlopef(&actor->spr, start.XY(), spriteGetSlope(actor));
|
||||
if ((start.Z > checkz) == ((actor->spr.cstat & CSTAT_SPRITE_YFLIP) == 0)) return -1;
|
||||
}
|
||||
if (!testpointinquad(result.XY(), points)) return -1;
|
||||
return factor;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -672,6 +782,7 @@ void neartag(const DVector3& pos, sectortype* startsect, DAngle angle, HitInfoBa
|
|||
|
||||
if (!(flags & NT_NoSpriteCheck))
|
||||
{
|
||||
double factor = 1;
|
||||
TSectIterator<DCoreActor> it(sect);
|
||||
while (auto actor = it.Next())
|
||||
{
|
||||
|
@ -681,8 +792,10 @@ void neartag(const DVector3& pos, sectortype* startsect, DAngle angle, HitInfoBa
|
|||
if (checkTag(&actor->spr))
|
||||
{
|
||||
DVector3 spot;
|
||||
if (intersectSprite(actor, pos, v, spot, 1 / 256.))
|
||||
double newfactor = intersectSprite(actor, pos, v, spot, factor - 1. / 65536.);
|
||||
if (newfactor > 0)
|
||||
{
|
||||
factor = newfactor;
|
||||
result.hitActor = actor;
|
||||
// return distance to sprite in a separate variable because there is
|
||||
// no means to determine what is for if both a sprite and wall are found.
|
||||
|
|
|
@ -260,8 +260,12 @@ void loaddefinitionsfile(const char* fn, bool cumulative = false, bool maingrp =
|
|||
bool calcChaseCamPos(DVector3& ppos, DCoreActor* pspr, sectortype** psectnum, DAngle ang, fixedhoriz horiz, double const interpfrac);
|
||||
int getslopeval(sectortype* sect, const DVector3& pos, double bazez);
|
||||
bool cansee(const DVector3& start, sectortype* sect1, const DVector3& end, sectortype* sect2);
|
||||
bool intersectSprite(DCoreActor* actor, const DVector3& start, const DVector3& end, DVector3& result, double displacement);
|
||||
double intersectSprite(DCoreActor* actor, const DVector3& start, const DVector3& direction, DVector3& result, double maxfactor);
|
||||
double intersectWallSprite(DCoreActor* actor, const DVector3& start, const DVector3& direction, DVector3& result, double maxfactor, bool checktex = false);
|
||||
double intersectFloorSprite(DCoreActor* actor, const DVector3& start, const DVector3& direction, DVector3& result, double maxfactor);
|
||||
double intersectSlopeSprite(DCoreActor* actor, const DVector3& start, const DVector3& direction, DVector3& result, double maxfactor);
|
||||
void neartag(const DVector3& start, sectortype* sect, DAngle angle, HitInfoBase& result, double neartagrange, int tagsearch);
|
||||
int testpointinquad(const DVector2& pt, const DVector2* quad);
|
||||
|
||||
|
||||
|
||||
|
@ -500,11 +504,24 @@ inline double SquareDist(double lx1, double ly1, double lx2, double ly2)
|
|||
return dx * dx + dy * dy;
|
||||
}
|
||||
|
||||
// This is for cases where only the factor is needed, e.g. intersectSprite which
|
||||
// needs to validate it before applying and also needs to apply it to a 3D vector.
|
||||
inline double NearestPointOnLineFast(double px, double py, double lx1, double ly1, double lx2, double ly2)
|
||||
{
|
||||
double wall_length = SquareDist(lx1, ly1, lx2, ly2);
|
||||
assert(wall_length > 0);
|
||||
return ((px - lx1) * (lx2 - lx1) + (py - ly1) * (ly2 - ly1)) / wall_length;
|
||||
}
|
||||
|
||||
|
||||
inline DVector2 NearestPointOnLine(double px, double py, double lx1, double ly1, double lx2, double ly2, bool clamp = true)
|
||||
{
|
||||
double wall_length = SquareDist(lx1, ly1, lx2, ly2);
|
||||
|
||||
if (wall_length == 0) return { lx1, ly1 };
|
||||
if (wall_length == 0)
|
||||
{
|
||||
return { lx1, ly1 };
|
||||
}
|
||||
|
||||
double t = ((px - lx1) * (lx2 - lx1) + (py - ly1) * (ly2 - ly1)) / wall_length;
|
||||
if (clamp)
|
||||
|
@ -593,11 +610,6 @@ inline double LinePlaneIntersect(const DVector3& start, const DVector3& trace, c
|
|||
return (dist - dotStart) / dotTrace; // we are only interested in the factor
|
||||
}
|
||||
|
||||
inline double LineHeightIntersect(double startz, double tracez, double dist)
|
||||
{
|
||||
return (dist - startz) / tracez; // we are only interested in the factor
|
||||
}
|
||||
|
||||
inline void alignceilslope(sectortype* sect, const DVector3& pos)
|
||||
{
|
||||
sect->setceilingslope(getslopeval(sect, pos, sect->ceilingz));
|
||||
|
|
|
@ -255,22 +255,6 @@ int RectClipMove(PLAYER* pp, DVector2* qpos)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
int testpointinquad(const DVector2& pt, const DVector2* quad)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
double dist = PointOnLineSide(pt.X, pt.Y, quad[i].X, quad[i].Y, quad[(i + 1) & 3].X - quad[i].X, quad[(i + 1) & 3].Y - quad[i].Y);
|
||||
if (dist > 0) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
short RectClipTurn(PLAYER* pp, DAngle new_angl, DVector2* qpos, DVector2* opos)
|
||||
{
|
||||
int i;
|
||||
|
|
|
@ -30,7 +30,6 @@ BEGIN_SW_NS
|
|||
Collision MultiClipMove(PLAYER* pp, double z, double floor_dist);
|
||||
int MultiClipTurn(PLAYER* pp, DAngle new_ang, double zz, double floordist);
|
||||
int RectClipMove(PLAYER* pp, DVector2* qpos);
|
||||
int testpointinquad(const DVector2& pt, const DVector2* quad);
|
||||
//short RectClipTurn(PLAYER* pp, short new_ang, int z, int floor_dist, int *qx, int *qy);
|
||||
short RectClipTurn(PLAYER* pp, short new_ang, int *qx, int *qy, int *ox, int *oy);
|
||||
END_SW_NS
|
||||
|
|
Loading…
Reference in a new issue