- consolidated all getslope code into a single function.

This also caches a wall's length to avoid taking the square root every single time for a slope calculation.
This commit is contained in:
Christoph Oelckers 2021-12-17 21:42:57 +01:00
parent bea394a734
commit 5f18109371
8 changed files with 118 additions and 167 deletions

View file

@ -333,22 +333,6 @@ int32_t getceilzofslopeptr(usectorptr_t sec, int32_t dax, int32_t day) ATTRIBU
int32_t getflorzofslopeptr(usectorptr_t sec, int32_t dax, int32_t day) ATTRIBUTE((nonnull(1)));
void getzsofslopeptr(usectorptr_t sec, int32_t dax, int32_t day,
int32_t *ceilz, int32_t *florz) ATTRIBUTE((nonnull(1,4,5)));
void yax_getzsofslope(int sectNum, int playerX, int playerY, int32_t* pCeilZ, int32_t* pFloorZ);
inline int32_t getceilzofslope(int sectnum, int32_t dax, int32_t day)
{
return getceilzofslopeptr((usectorptr_t)&sector[sectnum], dax, day);
}
inline int32_t getflorzofslope(int sectnum, int32_t dax, int32_t day)
{
return getflorzofslopeptr((usectorptr_t)&sector[sectnum], dax, day);
}
inline void getzsofslope(int sectnum, int32_t dax, int32_t day, int32_t *ceilz, int32_t *florz)
{
getzsofslopeptr((usectorptr_t)&sector[sectnum], dax, day, ceilz, florz);
}
inline void getcorrectzsofslope(int sectnum, int32_t dax, int32_t day, int32_t *ceilz, int32_t *florz)
{

View file

@ -225,13 +225,13 @@ static int cliptestsector(int const dasect, int const nextsect, int32_t const fl
break;
default:
{
int32_t daz = getflorzofslope(dasect, pos.x, pos.y);
int32_t daz2 = getflorzofslope(nextsect, pos.x, pos.y);
int32_t daz = getflorzofslopeptr(&sector[dasect], pos.x, pos.y);
int32_t daz2 = getflorzofslopeptr(sec2, pos.x, pos.y);
if (daz2 < daz-(1<<8) && (sec2->floorstat&1) == 0)
if (posz >= daz2-(flordist-1)) return 1;
daz = getceilzofslope(dasect, pos.x, pos.y);
daz2 = getceilzofslope(nextsect, pos.x, pos.y);
daz = getceilzofslopeptr(&sector[dasect], pos.x, pos.y);
daz2 = getceilzofslopeptr(sec2, pos.x, pos.y);
if (daz2 > daz+(1<<8) && (sec2->ceilingstat&1) == 0)
if (posz <= daz2+(ceildist-1)) return 1;
@ -784,28 +784,30 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect,
int32_t tempint2, tempint1 = INT32_MAX;
*sectnum = -1;
for (int j=numsectors-1; j>=0; j--)
if (inside_p(pos->x, pos->y, j) == 1)
for (int j = numsectors - 1; j >= 0; j--)
{
auto sect = &sector[j];
if (inside(pos->x, pos->y, sect) == 1)
{
if (enginecompatibility_mode != ENGINECOMPATIBILITY_19950829 && (sector[j].ceilingstat&2))
tempint2 = getceilzofslope(j, pos->x, pos->y) - pos->z;
if (enginecompatibility_mode != ENGINECOMPATIBILITY_19950829 && (sect->ceilingstat & CSTAT_SECTOR_SLOPE))
tempint2 = getceilzofslopeptr(sect, pos->x, pos->y) - pos->z;
else
tempint2 = sector[j].ceilingz - pos->z;
tempint2 = sect->ceilingz - pos->z;
if (tempint2 > 0)
{
if (tempint2 < tempint1)
{
*sectnum = (int16_t)j;
*sectnum = (int16_t)j;
tempint1 = tempint2;
}
}
else
{
if (enginecompatibility_mode != ENGINECOMPATIBILITY_19950829 && (sector[j].floorstat&2))
tempint2 = pos->z - getflorzofslope(j, pos->x, pos->y);
if (enginecompatibility_mode != ENGINECOMPATIBILITY_19950829 && (sect->ceilingstat & CSTAT_SECTOR_SLOPE))
tempint2 = pos->z - getflorzofslopeptr(sect, pos->x, pos->y);
else
tempint2 = pos->z - sector[j].floorz;
tempint2 = pos->z - sect->floorz;
if (tempint2 <= 0)
{
@ -819,6 +821,7 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect,
}
}
}
}
}
return clipReturn;

View file

@ -675,7 +675,7 @@ void dragpoint(int w, int32_t dax, int32_t day)
static inline int inside_z_p(int32_t const x, int32_t const y, int32_t const z, int const sectnum)
{
int32_t cz, fz;
getzsofslope(sectnum, x, y, &cz, &fz);
getzsofslopeptr(&sector[sectnum], x, y, &cz, &fz);
return (z >= cz && z <= fz && inside_p(x, y, sectnum));
}
@ -890,67 +890,6 @@ void renderRestoreTarget()
}
int32_t getceilzofslopeptr(usectorptr_t sec, int32_t dax, int32_t day)
{
if (!(sec->ceilingstat&2))
return sec->ceilingz;
auto const wal = (uwallptr_t)sec->firstWall();
auto const wal2 = (uwallptr_t)wal->point2Wall();
vec2_t const w = *(vec2_t const *)wal;
vec2_t const d = { wal2->x - w.x, wal2->y - w.y };
int const i = ksqrt(uhypsq(d.x,d.y))<<5;
if (i == 0) return sec->ceilingz;
int const j = DMulScale(d.x, day-w.y, -d.y, dax-w.x, 3);
int const shift = enginecompatibility_mode != ENGINECOMPATIBILITY_NONE ? 0 : 1;
return sec->ceilingz + (Scale(sec->ceilingheinum,j>>shift,i)<<shift);
}
int32_t getflorzofslopeptr(usectorptr_t sec, int32_t dax, int32_t day)
{
if (!(sec->floorstat&2))
return sec->floorz;
auto const wal = (uwallptr_t)sec->firstWall();
auto const wal2 = (uwallptr_t)wal->point2Wall();
vec2_t const w = *(vec2_t const *)wal;
vec2_t const d = { wal2->x - w.x, wal2->y - w.y };
int const i = ksqrt(uhypsq(d.x,d.y))<<5;
if (i == 0) return sec->floorz;
int const j = DMulScale(d.x, day-w.y, -d.y, dax-w.x, 3);
int const shift = enginecompatibility_mode != ENGINECOMPATIBILITY_NONE ? 0 : 1;
return sec->floorz + (Scale(sec->floorheinum,j>>shift,i)<<shift);
}
void getzsofslopeptr(usectorptr_t sec, int32_t dax, int32_t day, int32_t *ceilz, int32_t *florz)
{
*ceilz = sec->ceilingz; *florz = sec->floorz;
if (((sec->ceilingstat|sec->floorstat)&2) != 2)
return;
auto const wal = (uwallptr_t)sec->firstWall();
auto const wal2 = (uwallptr_t)wal->point2Wall();
vec2_t const d = { wal2->x - wal->x, wal2->y - wal->y };
int const i = ksqrt(uhypsq(d.x,d.y))<<5;
if (i == 0) return;
int const j = DMulScale(d.x,day-wal->y, -d.y,dax-wal->x, 3);
int const shift = enginecompatibility_mode != ENGINECOMPATIBILITY_NONE ? 0 : 1;
if (sec->ceilingstat&2)
*ceilz += Scale(sec->ceilingheinum,j>>shift,i)<<shift;
if (sec->floorstat&2)
*florz += Scale(sec->floorheinum,j>>shift,i)<<shift;
}
//
// alignceilslope
//

View file

@ -48,6 +48,7 @@ int32_t r_rortexturerange = 0;
int32_t r_rorphase = 0;
void calcSlope(const sectortype* sec, float xpos, float ypos, float* pceilz, float* pflorz);
int skiptile = -1;
FGameTexture* GetSkyTexture(int basetile, int lognumtiles, const int16_t* tilemap, int remap = 0);
@ -1159,7 +1160,7 @@ static void polymost_internal_nonparallaxed(FVector2 n0, FVector2 n1, float ryp0
if (have_floor)
{
if (globalposz > getflorzofslope(sectnum, globalposx, globalposy))
if (globalposz > getflorzofslopeptr(sec, globalposx, globalposy))
domostpolymethod = DAMETH_BACKFACECULL; //Back-face culling
if (domostpolymethod & DAMETH_MASKPROPS)
@ -1169,7 +1170,7 @@ static void polymost_internal_nonparallaxed(FVector2 n0, FVector2 n1, float ryp0
}
else
{
if (globalposz < getceilzofslope(sectnum, globalposx, globalposy))
if (globalposz < getceilzofslopeptr(sec, globalposx, globalposy))
domostpolymethod = DAMETH_BACKFACECULL; //Back-face culling
if (domostpolymethod & DAMETH_MASKPROPS)
@ -1245,60 +1246,21 @@ static inline int polymost_getclosestpointonwall(vec2_t const * const pos, int32
static float fgetceilzofslope(usectorptr_t sec, float dax, float day)
{
if (!(sec->ceilingstat&2))
return float(sec->ceilingz);
auto const wal = (uwallptr_t)sec->firstWall();
auto const wal2 = (uwallptr_t)wal->point2Wall();
vec2_t const w = *(vec2_t const *)wal;
vec2_t const d = { wal2->x - w.x, wal2->y - w.y };
int const i = ksqrt(uhypsq(d.x,d.y))<<5;
if (i == 0) return sec->ceilingz;
float const j = (d.x*(day-w.y)-d.y*(dax-w.x))*(1.f/8.f);
return float(sec->ceilingz) + (sec->ceilingheinum*j)/i;
float z;
calcSlope(sec, dax, day, &z, nullptr);
return z;
}
static float fgetflorzofslope(usectorptr_t sec, float dax, float day)
{
if (!(sec->floorstat&2))
return float(sec->floorz);
auto const wal = (uwallptr_t)sec->firstWall();
auto const wal2 = (uwallptr_t)wal->point2Wall();
vec2_t const w = *(vec2_t const *)wal;
vec2_t const d = { wal2->x - w.x, wal2->y - w.y };
int const i = ksqrt(uhypsq(d.x,d.y))<<5;
if (i == 0) return sec->floorz;
float const j = (d.x*(day-w.y)-d.y*(dax-w.x))*(1.f/8.f);
return float(sec->floorz) + (sec->floorheinum*j)/i;
float z;
calcSlope(sec, dax, day, nullptr, &z);
return z;
}
static void fgetzsofslope(usectorptr_t sec, float dax, float day, float* ceilz, float *florz)
{
*ceilz = float(sec->ceilingz); *florz = float(sec->floorz);
if (((sec->ceilingstat|sec->floorstat)&2) != 2)
return;
auto const wal = (uwallptr_t)sec->firstWall();
auto const wal2 = (uwallptr_t)wal->point2Wall();
vec2_t const d = { wal2->x - wal->x, wal2->y - wal->y };
int const i = ksqrt(uhypsq(d.x,d.y))<<5;
if (i == 0) return;
float const j = (d.x*(day-wal->y)-d.y*(dax-wal->x))*(1.f/8.f);
if (sec->ceilingstat&2)
*ceilz += (sec->ceilingheinum*j)/i;
if (sec->floorstat&2)
*florz += (sec->floorheinum*j)/i;
calcSlope(sec, dax, day, ceilz, florz);
}
static void polymost_flatskyrender(FVector2 const* const dpxy, int32_t const n, int32_t method, const vec2_16_t &tilesize)
@ -1620,7 +1582,7 @@ static void polymost_drawalls(int32_t const bunch)
}
else if (!(globalorientation&1))
{
int32_t fz = getflorzofslope(sectnum, globalposx, globalposy);
int32_t fz = getflorzofslopeptr(sec, globalposx, globalposy);
if (globalposz <= fz)
polymost_internal_nonparallaxed(n0, n1, ryp0, ryp1, x0, x1, fy0, fy1, sectnum, true);
}
@ -1673,7 +1635,7 @@ static void polymost_drawalls(int32_t const bunch)
}
else if (!(globalorientation&1))
{
int32_t cz = getceilzofslope(sectnum, globalposx, globalposy);
int32_t cz = getceilzofslopeptr(sec, globalposx, globalposy);
if (globalposz >= cz)
polymost_internal_nonparallaxed(n0, n1, ryp0, ryp1, x0, x1, cy0, cy1, sectnum, false);
}
@ -2383,11 +2345,11 @@ static void polymost_drawmaskwallinternal(int32_t wallIndex)
int32_t m0 = (int32_t)((wal2->x - wal->x) * t0 + wal->x);
int32_t m1 = (int32_t)((wal2->y - wal->y) * t0 + wal->y);
int32_t cz[4], fz[4];
getzsofslope(sectnum, m0, m1, &cz[0], &fz[0]);
getzsofslopeptr(sec, m0, m1, &cz[0], &fz[0]);
getzsofslopeptr(wal->nextSector(), m0, m1, &cz[1], &fz[1]);
m0 = (int32_t)((wal2->x - wal->x) * t1 + wal->x);
m1 = (int32_t)((wal2->y - wal->y) * t1 + wal->y);
getzsofslope(sectnum, m0, m1, &cz[2], &fz[2]);
getzsofslopeptr(sec, m0, m1, &cz[2], &fz[2]);
getzsofslopeptr(wal->nextSector(), m0, m1, &cz[3], &fz[3]);
float ryp0 = 1.f/p0.Y;

View file

@ -146,36 +146,79 @@ bool calcChaseCamPos(int* px, int* py, int* pz, spritetype* pspr, sectortype** p
//==========================================================================
//
// note that this returns values in renderer coordinate space with inverted sign!
// consolidated slope calculation
//
//==========================================================================
void calcSlope(const sectortype* sec, float xpos, float ypos, float* pceilz, float* pflorz)
{
int bits = 0;
if (pceilz)
{
bits |= sec->ceilingstat;
*pceilz = float(sec->ceilingz);
}
if (pflorz)
{
bits |= sec->floorstat;
*pflorz = float(sec->floorz);
}
if ((bits & CSTAT_SECTOR_SLOPE) == CSTAT_SECTOR_SLOPE)
{
auto wal = sec->firstWall();
int len = wal->Length();
if (len != 0)
{
float den = (wal->deltax() * (float(ypos - wal->y)) - wal->deltay() * (float(xpos - wal->x))) * (1.f / 8.f);
if (pceilz && sec->ceilingstat & CSTAT_SECTOR_SLOPE) *pceilz += (sec->ceilingheinum * den) / len;
if (pflorz && sec->floorstat & CSTAT_SECTOR_SLOPE) *pflorz += (sec->floorheinum * den) / len;
}
}
}
//==========================================================================
//
// for the renderer (Polymost variants are in polymost.cpp)
//
//==========================================================================
void PlanesAtPoint(const sectortype* sec, int dax, int day, float* pceilz, float* pflorz)
{
float ceilz = float(sec->ceilingz);
float florz = float(sec->floorz);
if (((sec->ceilingstat | sec->floorstat) & CSTAT_SECTOR_SLOPE) == CSTAT_SECTOR_SLOPE)
{
auto wal = sec->firstWall();
auto wal2 = wal->point2Wall();
float dx = float(wal2->x - wal->x);
float dy = float(wal2->y - wal->y);
int i = (int)sqrt(dx * dx + dy * dy) << 5; // length of sector's first wall.
if (i != 0)
{
float const j = (dx * (float(day - wal->y)) - dy * (float(dax - wal->x))) * (1.f / 8.f);
if (sec->ceilingstat & CSTAT_SECTOR_SLOPE) ceilz += (sec->ceilingheinum * j) / i;
if (sec->floorstat & CSTAT_SECTOR_SLOPE) florz += (sec->floorheinum * j) / i;
}
}
// Scale to render coordinates.
if (pceilz) *pceilz = ceilz * -(1.f / 256.f);
if (pflorz) *pflorz = florz * -(1.f / 256.f);
calcSlope(sec, dax, day, pceilz, pflorz);
if (pceilz) *pceilz *= -(1 / 256.f);
if (pflorz) *pflorz *= -(1 / 256.f);
}
//==========================================================================
//
// for the games
//
//==========================================================================
int32_t getceilzofslopeptr(usectorptr_t sec, int32_t dax, int32_t day)
{
float z;
calcSlope(sec, dax, day, &z, nullptr);
return int(z);
}
int32_t getflorzofslopeptr(usectorptr_t sec, int32_t dax, int32_t day)
{
float z;
calcSlope(sec, dax, day, nullptr, &z);
return int(z);
}
void getzsofslopeptr(usectorptr_t sec, int32_t dax, int32_t day, int32_t* ceilz, int32_t* florz)
{
float c, f;
calcSlope(sec, dax, day, &c, &f);
*ceilz = int(c);
*florz = int(f);
}
//==========================================================================
//
// Calculate the position of a wall sprite in the world

View file

@ -59,6 +59,14 @@ TArray<walltype> wall;
TArray<sectortype> sectorbackup;
TArray<walltype> wallbackup;
void walltype::calcLength()
{
lengthflags &= ~1;
point2Wall()->lengthflags &= ~2;
auto d = delta();
length = (int)sqrt(d.x * d.x + d.y * d.y) << 5;
}
// needed for skipping over to get the map size first.
enum
{

View file

@ -334,6 +334,8 @@ struct walltype
int deltax() const { return point2Wall()->x - x; }
int deltay() const { return point2Wall()->y - y; }
bool twoSided() const { return nextsector >= 0; }
int Length();
void calcLength(); // this is deliberately not inlined and stored in a file where it can't be found at compile time.
void move(int newx, int newy);
void moved();
@ -649,6 +651,16 @@ inline void walltype::move(int newx, int newy)
sectorp()->dirty = EDirty::AllDirty;
}
inline int walltype::Length()
{
if ((lengthflags & 1) || (point2Wall()->lengthflags & 2))
{
// value is stale, recreate
calcLength();
}
return length;
}
//=============================================================================
//
// Map loader stuff

View file

@ -19,7 +19,7 @@ void collectTSpritesForPortal(int x, int y, int i, int interpolation)
int top, bottom;
GetSpriteExtents(pSprite, &top, &bottom);
int zCeil, zFloor;
getzsofslope(nSector, pSprite->x, pSprite->y, &zCeil, &zFloor);
getzsofslopeptr(&sector[nSector], pSprite->x, pSprite->y, &zCeil, &zFloor);
if (pSprite->statnum == kStatDude && (top < zCeil || bottom > zFloor))
{
int j = i;