mirror of
https://github.com/DrBeef/Raze.git
synced 2025-01-19 15:40:58 +00:00
- rewrote getzrange
Not using any old Build code anymore. Aside from the trivial stuff this uses code from Doom and SW instead.
This commit is contained in:
parent
13d643deb5
commit
8e9ddf370c
6 changed files with 277 additions and 252 deletions
|
@ -111,14 +111,6 @@ void setVideoMode();
|
|||
class F2DDrawer;
|
||||
|
||||
|
||||
void getzrange(const DVector3& pos, sectortype* sect, double* ceilz, CollisionBase& ceilhit, double* florz, CollisionBase& florhit, int32_t walldist, uint32_t cliptype);
|
||||
inline
|
||||
void getzrange(const DVector3& pos, sectortype* sect, double* ceilz, CollisionBase& ceilhit, double* florz, CollisionBase& florhit, double walldist, uint32_t cliptype)
|
||||
{
|
||||
getzrange(pos, sect, ceilz, ceilhit, florz, florhit, int(walldist * worldtoint), cliptype);
|
||||
}
|
||||
|
||||
|
||||
struct HitInfoBase;
|
||||
|
||||
inline int32_t krand(void)
|
||||
|
|
|
@ -256,34 +256,6 @@ static inline void keepaway(int32_t *x, int32_t *y, int32_t w)
|
|||
while (1);
|
||||
}
|
||||
|
||||
static int get_floorspr_clipyou(vec2_t const v1, vec2_t const v2, vec2_t const v3, vec2_t const v4)
|
||||
{
|
||||
int clipyou = 0;
|
||||
|
||||
if ((v1.Y^v2.Y) < 0)
|
||||
{
|
||||
if ((v1.X^v2.X) < 0) clipyou ^= (v1.X*v2.Y < v2.X*v1.Y)^(v1.Y<v2.Y);
|
||||
else if (v1.X >= 0) clipyou ^= 1;
|
||||
}
|
||||
if ((v2.Y^v3.Y) < 0)
|
||||
{
|
||||
if ((v2.X^v3.X) < 0) clipyou ^= (v2.X*v3.Y < v3.X*v2.Y)^(v2.Y<v3.Y);
|
||||
else if (v2.X >= 0) clipyou ^= 1;
|
||||
}
|
||||
if ((v3.Y^v4.Y) < 0)
|
||||
{
|
||||
if ((v3.X^v4.X) < 0) clipyou ^= (v3.X*v4.Y < v4.X*v3.Y)^(v3.Y<v4.Y);
|
||||
else if (v3.X >= 0) clipyou ^= 1;
|
||||
}
|
||||
if ((v4.Y^v1.Y) < 0)
|
||||
{
|
||||
if ((v4.X^v1.X) < 0) clipyou ^= (v4.X*v1.Y < v1.X*v4.Y)^(v4.Y<v1.Y);
|
||||
else if (v4.X >= 0) clipyou ^= 1;
|
||||
}
|
||||
|
||||
return clipyou;
|
||||
}
|
||||
|
||||
static int32_t getwalldist(vec2_t const in, int const wallnum)
|
||||
{
|
||||
auto dvec = NearestPointOnWall(in.X * maptoworld, in.Y * maptoworld, &wall[wallnum]);
|
||||
|
@ -882,212 +854,3 @@ int pushmove_(vec3_t *const vect, int *const sectnum,
|
|||
|
||||
return bad;
|
||||
}
|
||||
|
||||
//
|
||||
// getzrange
|
||||
//
|
||||
|
||||
|
||||
void getzrange(const DVector3& pos_, sectortype* sect, double* ceilz_, CollisionBase& ceilhit, double* florz_, CollisionBase& florhit, int32_t walldist, uint32_t cliptype)
|
||||
{
|
||||
vec3_t pos(int(pos_.X * worldtoint), int(pos_.Y * worldtoint), int(pos_.Z * zworldtoint) );
|
||||
|
||||
if (sect == nullptr)
|
||||
{
|
||||
*ceilz_ = -FLT_MAX; ceilhit.setVoid();
|
||||
*florz_ = FLT_MAX; florhit.setVoid();
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t clipsectcnt = 0;
|
||||
|
||||
int32_t clipspritecnt = 0;
|
||||
|
||||
//Extra walldist for sprites on sector lines
|
||||
const int32_t extradist = walldist+MAXCLIPDIST+1;
|
||||
const int32_t xmin = pos.X-extradist, ymin = pos.Y-extradist;
|
||||
const int32_t xmax = pos.X+extradist, ymax = pos.Y+extradist;
|
||||
|
||||
const int32_t dawalclipmask = (cliptype&65535);
|
||||
const int32_t dasprclipmask = (cliptype >> 16);
|
||||
|
||||
vec2_t closest = pos.vec2;
|
||||
int sectnum = ::sectnum(sect);
|
||||
if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE)
|
||||
{
|
||||
DVector2 v;
|
||||
SquareDistToSector(closest.X * inttoworld, closest.Y * inttoworld, §or[sectnum], &v);
|
||||
closest = { int(v.X * worldtoint), int(v.Y * worldtoint) };
|
||||
}
|
||||
|
||||
getzsofslopeptr(sect, closest.X * inttoworld, closest.Y * inttoworld, ceilz_, florz_);
|
||||
ceilhit.setSector(sect);
|
||||
florhit.setSector(sect);
|
||||
|
||||
clipsectorlist[0] = sectnum;
|
||||
clipsectnum = 1;
|
||||
clipspritenum = 0;
|
||||
clipsectormap.Zero();
|
||||
clipsectormap.Set(sectnum);
|
||||
|
||||
do //Collect sectors inside your square first
|
||||
{
|
||||
////////// Walls //////////
|
||||
|
||||
auto const startsec = §or[clipsectorlist[clipsectcnt]];
|
||||
|
||||
for(auto&wal : wallsofsector(startsec))
|
||||
{
|
||||
if (wal.twoSided())
|
||||
{
|
||||
auto nextsect = wal.nextSector();
|
||||
vec2_t const v1 = wal.wall_int_pos();
|
||||
vec2_t const v2 = wal.point2Wall()->wall_int_pos();
|
||||
|
||||
if ((v1.X < xmin && (v2.X < xmin)) || (v1.X > xmax && v2.X > xmax) ||
|
||||
(v1.Y < ymin && (v2.Y < ymin)) || (v1.Y > ymax && v2.Y > ymax))
|
||||
continue;
|
||||
|
||||
vec2_t const d = { v2.X-v1.X, v2.Y-v1.Y };
|
||||
if (d.X*(pos.Y-v1.Y) < (pos.X-v1.X)*d.Y) continue; //back
|
||||
|
||||
vec2_t da = { (d.X > 0) ? d.X*(ymin-v1.Y) : d.X*(ymax-v1.Y),
|
||||
(d.Y > 0) ? d.Y*(xmax-v1.X) : d.Y*(xmin-v1.X) };
|
||||
|
||||
if (da.X >= da.Y)
|
||||
continue;
|
||||
|
||||
if (wal.cstat & EWallFlags::FromInt(dawalclipmask)) continue; // XXX?
|
||||
|
||||
if (((nextsect->ceilingstat & CSTAT_SECTOR_SKY) == 0) && (pos.Z <= int(nextsect->ceilingz * zworldtoint)+(3<<8))) continue;
|
||||
if (((nextsect->floorstat & CSTAT_SECTOR_SKY) == 0) && (pos.Z >= int(nextsect->floorz * zworldtoint)-(3<<8))) continue;
|
||||
|
||||
int nextsectno = ::sectnum(nextsect);
|
||||
if (!clipsectormap[nextsectno])
|
||||
addclipsect(nextsectno);
|
||||
|
||||
if (((v1.X < xmin + MAXCLIPDIST) && (v2.X < xmin + MAXCLIPDIST)) ||
|
||||
((v1.X > xmax - MAXCLIPDIST) && (v2.X > xmax - MAXCLIPDIST)) ||
|
||||
((v1.Y < ymin + MAXCLIPDIST) && (v2.Y < ymin + MAXCLIPDIST)) ||
|
||||
((v1.Y > ymax - MAXCLIPDIST) && (v2.Y > ymax - MAXCLIPDIST)))
|
||||
continue;
|
||||
|
||||
if (d.X > 0) da.X += d.X*MAXCLIPDIST; else da.X -= d.X*MAXCLIPDIST;
|
||||
if (d.Y > 0) da.Y -= d.Y*MAXCLIPDIST; else da.Y += d.Y*MAXCLIPDIST;
|
||||
if (da.X >= da.Y)
|
||||
continue;
|
||||
//It actually got here, through all the continue's!!!
|
||||
double daz = 0, daz2 = 0;
|
||||
closest = pos.vec2;
|
||||
if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE)
|
||||
{
|
||||
DVector2 v;
|
||||
SquareDistToSector(closest.X * inttoworld, closest.Y * inttoworld, §or[nextsectno], &v);
|
||||
closest = { int(v.X * worldtoint), int(v.Y * worldtoint) };
|
||||
}
|
||||
|
||||
getzsofslopeptr(nextsect, closest.X * inttoworld,closest.Y * inttoworld, &daz,&daz2);
|
||||
|
||||
{
|
||||
if (daz > *ceilz_)
|
||||
*ceilz_ = daz, ceilhit.setSector(nextsect);
|
||||
|
||||
if (daz2 < *florz_)
|
||||
*florz_ = daz2, florhit.setSector(nextsect);
|
||||
}
|
||||
}
|
||||
}
|
||||
clipsectcnt++;
|
||||
}
|
||||
while (clipsectcnt < clipsectnum || clipspritecnt < clipspritenum);
|
||||
|
||||
////////// Sprites //////////
|
||||
|
||||
if (dasprclipmask)
|
||||
for (int i=0; i<clipsectnum; i++)
|
||||
{
|
||||
if (!validSectorIndex(clipsectorlist[i])) continue; // we got a deleted sprite in here somewhere. Skip this entry.
|
||||
TSectIterator<DCoreActor> it(clipsectorlist[i]);
|
||||
while (auto actor = it.Next())
|
||||
{
|
||||
const int32_t cstat = actor->spr.cstat;
|
||||
int32_t daz = 0, daz2 = 0;
|
||||
|
||||
if (actor->spr.cstat2 & CSTAT2_SPRITE_NOFIND) continue;
|
||||
if (cstat&dasprclipmask)
|
||||
{
|
||||
int32_t clipyou = 0;
|
||||
|
||||
vec2_t v1 = actor->int_pos().vec2;
|
||||
|
||||
switch (cstat & CSTAT_SPRITE_ALIGNMENT_MASK)
|
||||
{
|
||||
case CSTAT_SPRITE_ALIGNMENT_FACING:
|
||||
{
|
||||
int32_t k = walldist+(actor->int_clipdist())+1;
|
||||
if ((abs(v1.X-pos.X) <= k) && (abs(v1.Y-pos.Y) <= k))
|
||||
{
|
||||
daz = actor->int_pos().Z + actor->GetOffsetAndHeight(k);
|
||||
daz2 = daz - k;
|
||||
clipyou = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CSTAT_SPRITE_ALIGNMENT_WALL:
|
||||
{
|
||||
vec2_t v2;
|
||||
get_wallspr_points(actor, &v1.X, &v2.X, &v1.Y, &v2.Y);
|
||||
|
||||
if (clipinsideboxline(pos.X,pos.Y,v1.X,v1.Y,v2.X,v2.Y,walldist+1) != 0)
|
||||
{
|
||||
int32_t k;
|
||||
daz = actor->int_pos().Z + actor->GetOffsetAndHeight(k);
|
||||
daz2 = daz-k;
|
||||
clipyou = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CSTAT_SPRITE_ALIGNMENT_FLOOR:
|
||||
case CSTAT_SPRITE_ALIGNMENT_SLOPE:
|
||||
{
|
||||
daz = spriteGetZOfSlope(&actor->spr, pos.X, pos.Y, spriteGetSlope(actor));
|
||||
daz2 = daz;
|
||||
|
||||
if ((cstat & CSTAT_SPRITE_ONE_SIDE) != 0 && (pos.Z > daz) == ((cstat & CSTAT_SPRITE_YFLIP)==0))
|
||||
continue;
|
||||
|
||||
vec2_t v2, v3, v4;
|
||||
get_floorspr_points(actor, pos.X, pos.Y, &v1.X, &v2.X, &v3.X, &v4.X,
|
||||
&v1.Y, &v2.Y, &v3.Y, &v4.Y);
|
||||
|
||||
vec2_t const da = { MulScale(bcos(actor->int_ang() - 256), walldist + 4, 14),
|
||||
MulScale(bsin(actor->int_ang() - 256), walldist + 4, 14) };
|
||||
|
||||
v1.X += da.X; v2.X -= da.Y; v3.X -= da.X; v4.X += da.Y;
|
||||
v1.Y += da.Y; v2.Y += da.X; v3.Y -= da.Y; v4.Y -= da.X;
|
||||
|
||||
clipyou = get_floorspr_clipyou(v1, v2, v3, v4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (clipyou != 0)
|
||||
{
|
||||
if ((pos.Z > daz) && (daz * zinttoworld > *ceilz_))
|
||||
{
|
||||
*ceilz_ = daz * zinttoworld;
|
||||
ceilhit.setSprite(actor);
|
||||
}
|
||||
|
||||
if ((pos.Z < daz2) && (daz2 * zinttoworld < *florz_))
|
||||
{
|
||||
*florz_ = daz2 * zinttoworld;
|
||||
florhit.setSprite(actor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,12 +51,6 @@ inline double PointOnLineSide(double x, double y, double linex, double liney, do
|
|||
return (x - linex) * deltay - (y - liney) * deltax;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline double PointOnLineSide(const TVector2<T>& pos, const TVector2<T>& linestart, const TVector2<T>& lineend)
|
||||
{
|
||||
return (pos.X - linestart.X) * (lineend.Y - linestart.Y) - (pos.Y - linestart.Y) * (lineend.X - linestart.X);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -175,3 +169,63 @@ inline double LinePlaneIntersect(const DVector3& start, const DVector3& trace, c
|
|||
return (dist - dotStart) / dotTrace; // we are only interested in the factor
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// BoxOnLineSide
|
||||
//
|
||||
// Based on Doom's, but rewritten to be standalone
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
inline int BoxOnLineSide(const DVector2& boxtl, const DVector2& boxbr, const DVector2& start, const DVector2& delta)
|
||||
{
|
||||
int p1;
|
||||
int p2;
|
||||
|
||||
if (delta.X == 0)
|
||||
{
|
||||
p1 = boxbr.X < start.X;
|
||||
p2 = boxtl.X < start.X;
|
||||
if (delta.Y < 0)
|
||||
{
|
||||
p1 ^= 1;
|
||||
p2 ^= 1;
|
||||
}
|
||||
}
|
||||
else if (delta.Y == 0)
|
||||
{
|
||||
p1 = boxtl.Y > start.Y;
|
||||
p2 = boxbr.Y > start.Y;
|
||||
if (delta.X < 0)
|
||||
{
|
||||
p1 ^= 1;
|
||||
p2 ^= 1;
|
||||
}
|
||||
}
|
||||
else if (delta.X * delta.Y <= 0)
|
||||
{
|
||||
p1 = PointOnLineSide(boxtl.X, boxtl.Y, start.X, start.Y, delta.X, delta.Y) > 0;
|
||||
p2 = PointOnLineSide(boxbr.X, boxbr.Y, start.X, start.Y, delta.X, delta.Y) > 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
p1 = PointOnLineSide(boxbr.X, boxtl.Y, start.X, start.Y, delta.X, delta.Y) > 0;
|
||||
p2 = PointOnLineSide(boxtl.X, boxbr.Y, start.X, start.Y, delta.X, delta.Y) > 0;
|
||||
}
|
||||
|
||||
return (p1 == p2) ? p1 : -1;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// BoxInRange
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
inline bool BoxInRange(const DVector2& boxtl, const DVector2& boxbr, const DVector2& start, const DVector2& end)
|
||||
{
|
||||
return boxtl.X < max(start.X, end.X) &&
|
||||
boxbr.X > min(start.X, end.X) &&
|
||||
boxtl.Y < max(start.Y, end.Y) &&
|
||||
boxbr.Y > min(start.Y, end.Y);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include "hw_voxels.h"
|
||||
|
||||
IntRect viewport3d;
|
||||
constexpr double MAXCLIPDISTF = 64;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
|
@ -869,6 +870,215 @@ int hitscan(const DVector3& start, const sectortype* startsect, const DVector3&
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool checkRangeOfWall(walltype* wal, EWallFlags flagmask, const DVector3& pos, double maxdist, double* theZs)
|
||||
{
|
||||
if (!wal->twoSided()) return false;
|
||||
if (wal->cstat & flagmask) return false;
|
||||
if (PointOnLineSide(pos.XY(), wal) > 0) return false;
|
||||
|
||||
auto nextsect = wal->nextSector();
|
||||
|
||||
// Rather pointless sky check that needs to be kept...
|
||||
if (((nextsect->ceilingstat & CSTAT_SECTOR_SKY) == 0) && (pos.Z <= nextsect->ceilingz + 3)) return false;
|
||||
if (((nextsect->floorstat & CSTAT_SECTOR_SKY) == 0) && (pos.Z >= nextsect->floorz - 3)) return false;
|
||||
|
||||
auto pos1 = wal->pos;
|
||||
auto pos2 = wal->point2Wall()->pos;
|
||||
|
||||
// Checks borrowed from GZDoom.
|
||||
DVector2 boxtl = pos - DVector2(maxdist, maxdist);
|
||||
DVector2 boxbr = pos + DVector2(maxdist, maxdist);
|
||||
if (!BoxInRange(boxtl, boxbr, pos1, pos2)) return false;
|
||||
if (BoxOnLineSide(boxtl, boxbr, pos1, pos2 - pos1) != -1) return false;
|
||||
|
||||
auto closest = pos.XY();
|
||||
if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE) // todo: need to check if it makes sense to have this always on.
|
||||
SquareDistToSector(closest.X, closest.Y, nextsect, &closest);
|
||||
|
||||
getzsofslopeptr(nextsect, closest.X, closest.Y, &theZs[0], &theZs[1]);
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool checkRangeOfFaceSprite(DCoreActor* itActor, const DVector3& pos, double maxdist, double* theZs)
|
||||
{
|
||||
double dist = maxdist + itActor->fClipdist();
|
||||
if (abs(pos.X - itActor->spr.pos.X) > dist || abs(pos.Y - itActor->spr.pos.Y) > dist) return false; // Just like Doom: actors are square...
|
||||
double h;
|
||||
theZs[0] = itActor->spr.pos.Z + itActor->GetOffsetAndHeight(h);
|
||||
theZs[1] = theZs[0] - h;
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool checkRangeOfWallSprite(DCoreActor* itActor, const DVector3& pos, double maxdist, double* theZs)
|
||||
{
|
||||
int t = itActor->time;
|
||||
if ((t >= 485 && t <= 487) || t == 315)
|
||||
{
|
||||
int a = 0;
|
||||
}
|
||||
DVector2 verts[2];
|
||||
GetWallSpritePosition(&itActor->spr, itActor->spr.pos.XY(), verts);
|
||||
if (IsCloseToLine(pos.XY(), verts[0], verts[1], maxdist) == EClose::Outside) return false;
|
||||
double h;
|
||||
theZs[0] = itActor->spr.pos.Z + itActor->GetOffsetAndHeight(h);
|
||||
theZs[1] = theZs[0] - h;
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool checkRangeOfFloorSprite(DCoreActor* itActor, const DVector3& pos, double maxdist, double& theZ)
|
||||
{
|
||||
int cstat = itActor->spr.cstat;
|
||||
if ((cstat & (CSTAT_SPRITE_ALIGNMENT_MASK)) < (CSTAT_SPRITE_ALIGNMENT_FLOOR))
|
||||
return false;
|
||||
|
||||
double fdaz = spriteGetZOfSlopef(&itActor->spr, pos.XY(), spriteGetSlope(itActor));
|
||||
|
||||
// Only check if sprite's 2-sided or your on the 1-sided side
|
||||
if (((cstat & CSTAT_SPRITE_ONE_SIDE) != 0) && ((pos.Z > fdaz) == ((cstat & CSTAT_SPRITE_YFLIP) == 0)))
|
||||
return false;
|
||||
|
||||
DVector2 out[4];
|
||||
GetFlatSpritePosition(itActor, itActor->spr.pos.XY(), out);
|
||||
|
||||
// expand the area to cover 'maxdist' units more on each side. (i.e. move the edges out)
|
||||
auto expand = (itActor->spr.angle - DAngle45).ToVector() * (maxdist + 0.25); // that's surely not accurate but here we must match Build's original value.
|
||||
out[0] += expand;
|
||||
out[1] += expand.Rotated90CCW();
|
||||
out[2] -= expand;
|
||||
out[3] += expand.Rotated90CW();
|
||||
|
||||
if (!insidePoly(pos.X, pos.Y, out, 4)) return false;
|
||||
|
||||
theZ = fdaz;
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void getzrange(const DVector3& pos, sectortype* sect, double* ceilz, CollisionBase& ceilhit, double* florz, CollisionBase& florhit, double maxdist, uint32_t cliptype)
|
||||
{
|
||||
if (sect == nullptr)
|
||||
{
|
||||
*ceilz = -FLT_MAX; ceilhit.setVoid();
|
||||
*florz = FLT_MAX; florhit.setVoid();
|
||||
return;
|
||||
}
|
||||
|
||||
const EWallFlags dawalclipmask = EWallFlags::FromInt(cliptype & 65535);
|
||||
const ESpriteFlags dasprclipmask = ESpriteFlags::FromInt(cliptype >> 16);
|
||||
|
||||
auto closest = pos.XY();
|
||||
if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE)
|
||||
SquareDistToSector(closest.X, closest.Y, sect, &closest);
|
||||
|
||||
getzsofslopeptr(sect, closest, ceilz, florz);
|
||||
ceilhit.setSector(sect);
|
||||
florhit.setSector(sect);
|
||||
|
||||
double theZs[2];
|
||||
|
||||
BFSSectorSearch search(sect);
|
||||
while (auto sec = search.GetNext())
|
||||
{
|
||||
for (auto& wal : wallsofsector(sec))
|
||||
{
|
||||
if (checkRangeOfWall(&wal, EWallFlags::FromInt(dawalclipmask), pos, maxdist + 1 / 16., theZs))
|
||||
{
|
||||
auto nsec = wal.nextSector();
|
||||
search.Add(nsec);
|
||||
if (/*(pos.Z > theZs[0]) &&*/ (theZs[0] > *ceilz))
|
||||
{
|
||||
*ceilz = theZs[0];
|
||||
ceilhit.setSector(nsec);
|
||||
}
|
||||
|
||||
if (/*(pos.Z < theZs[1]) &&*/ (theZs[1] < *florz))
|
||||
{
|
||||
*florz = theZs[1];
|
||||
florhit.setSector(nsec);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dasprclipmask)
|
||||
{
|
||||
search.Rewind();
|
||||
while (auto sec = search.GetNext())
|
||||
{
|
||||
TSectIterator<DCoreActor> it(sec);
|
||||
while (auto actor = it.Next())
|
||||
{
|
||||
const int32_t cstat = actor->spr.cstat;
|
||||
|
||||
if (actor->spr.cstat2 & CSTAT2_SPRITE_NOFIND) continue;
|
||||
if (cstat & dasprclipmask)
|
||||
{
|
||||
switch (cstat & CSTAT_SPRITE_ALIGNMENT_MASK)
|
||||
{
|
||||
case CSTAT_SPRITE_ALIGNMENT_FACING:
|
||||
if (!checkRangeOfFaceSprite(actor, pos, maxdist + 1 / 16., theZs)) continue;
|
||||
break;
|
||||
|
||||
case CSTAT_SPRITE_ALIGNMENT_WALL:
|
||||
if (!checkRangeOfWallSprite(actor, pos, maxdist + 1 / 16., theZs)) continue;
|
||||
break;
|
||||
|
||||
case CSTAT_SPRITE_ALIGNMENT_FLOOR:
|
||||
case CSTAT_SPRITE_ALIGNMENT_SLOPE:
|
||||
if (!checkRangeOfFloorSprite(actor, pos, maxdist, theZs[0])) continue;
|
||||
theZs[1] = theZs[0];
|
||||
break;
|
||||
}
|
||||
|
||||
// Clipping time!
|
||||
if ((pos.Z > theZs[0]) && (theZs[0] > *ceilz))
|
||||
{
|
||||
*ceilz = theZs[0];
|
||||
ceilhit.setSprite(actor);
|
||||
}
|
||||
|
||||
if ((pos.Z < theZs[1]) && (theZs[1] < *florz))
|
||||
{
|
||||
*florz = theZs[1];
|
||||
florhit.setSprite(actor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
|
@ -253,6 +253,12 @@ void neartag(const DVector3& start, sectortype* sect, DAngle angle, HitInfoBase&
|
|||
int testpointinquad(const DVector2& pt, const DVector2* quad);
|
||||
int hitscan(const DVector3& start, const sectortype* startsect, const DVector3& vect, HitInfoBase& hitinfo, unsigned cliptype, double maxrange = -1);
|
||||
|
||||
bool checkRangeOfWall(walltype* wal, EWallFlags flagmask, const DVector3& pos, double maxdist, double* theZs);
|
||||
bool checkRangeOfFaceSprite(DCoreActor* itActor, const DVector3& pos, double maxdist, double* theZs);
|
||||
bool checkRangeOfWallSprite(DCoreActor* itActor, const DVector3& pos, double maxdist, double* theZs);
|
||||
bool checkRangeOfFloorSprite(DCoreActor* itActor, const DVector3& pos, double maxdist, double& theZ);
|
||||
void getzrange(const DVector3& pos, sectortype* sect, double* ceilz, CollisionBase& ceilhit, double* florz, CollisionBase& florhit, double walldist, uint32_t cliptype);
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1242,7 +1242,7 @@ void HWWall::ProcessWallSprite(HWDrawInfo* di, tspritetype* spr, sectortype* sec
|
|||
return; // nothing left to render.
|
||||
|
||||
// If the sprite is backward, flip it around so that we have guaranteed orientation when this is about to be sorted.
|
||||
if (PointOnLineSide(di->Viewpoint.Pos.XY(), DVector2(glseg.x1, glseg.y1), DVector2(glseg.x2, glseg.y2)) < 0)
|
||||
if (PointOnLineSide(di->Viewpoint.Pos.X, di->Viewpoint.Pos.Y, glseg.x1, glseg.y1, glseg.x2 - glseg.x1, glseg.y2 - glseg.y1 ) < 0)
|
||||
{
|
||||
std::swap(glseg.x1, glseg.x2);
|
||||
std::swap(glseg.y1, glseg.y2);
|
||||
|
|
Loading…
Reference in a new issue