- 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))); 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, void getzsofslopeptr(usectorptr_t sec, int32_t dax, int32_t day,
int32_t *ceilz, int32_t *florz) ATTRIBUTE((nonnull(1,4,5))); 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) 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; break;
default: default:
{ {
int32_t daz = getflorzofslope(dasect, pos.x, pos.y); int32_t daz = getflorzofslopeptr(&sector[dasect], pos.x, pos.y);
int32_t daz2 = getflorzofslope(nextsect, pos.x, pos.y); int32_t daz2 = getflorzofslopeptr(sec2, pos.x, pos.y);
if (daz2 < daz-(1<<8) && (sec2->floorstat&1) == 0) if (daz2 < daz-(1<<8) && (sec2->floorstat&1) == 0)
if (posz >= daz2-(flordist-1)) return 1; if (posz >= daz2-(flordist-1)) return 1;
daz = getceilzofslope(dasect, pos.x, pos.y); daz = getceilzofslopeptr(&sector[dasect], pos.x, pos.y);
daz2 = getceilzofslope(nextsect, pos.x, pos.y); daz2 = getceilzofslopeptr(sec2, pos.x, pos.y);
if (daz2 > daz+(1<<8) && (sec2->ceilingstat&1) == 0) if (daz2 > daz+(1<<8) && (sec2->ceilingstat&1) == 0)
if (posz <= daz2+(ceildist-1)) return 1; 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; int32_t tempint2, tempint1 = INT32_MAX;
*sectnum = -1; *sectnum = -1;
for (int j=numsectors-1; j>=0; j--) for (int j = numsectors - 1; j >= 0; j--)
if (inside_p(pos->x, pos->y, j) == 1) {
auto sect = &sector[j];
if (inside(pos->x, pos->y, sect) == 1)
{ {
if (enginecompatibility_mode != ENGINECOMPATIBILITY_19950829 && (sector[j].ceilingstat&2)) if (enginecompatibility_mode != ENGINECOMPATIBILITY_19950829 && (sect->ceilingstat & CSTAT_SECTOR_SLOPE))
tempint2 = getceilzofslope(j, pos->x, pos->y) - pos->z; tempint2 = getceilzofslopeptr(sect, pos->x, pos->y) - pos->z;
else else
tempint2 = sector[j].ceilingz - pos->z; tempint2 = sect->ceilingz - pos->z;
if (tempint2 > 0) if (tempint2 > 0)
{ {
if (tempint2 < tempint1) if (tempint2 < tempint1)
{ {
*sectnum = (int16_t)j; *sectnum = (int16_t)j;
tempint1 = tempint2; tempint1 = tempint2;
} }
} }
else else
{ {
if (enginecompatibility_mode != ENGINECOMPATIBILITY_19950829 && (sector[j].floorstat&2)) if (enginecompatibility_mode != ENGINECOMPATIBILITY_19950829 && (sect->ceilingstat & CSTAT_SECTOR_SLOPE))
tempint2 = pos->z - getflorzofslope(j, pos->x, pos->y); tempint2 = pos->z - getflorzofslopeptr(sect, pos->x, pos->y);
else else
tempint2 = pos->z - sector[j].floorz; tempint2 = pos->z - sect->floorz;
if (tempint2 <= 0) if (tempint2 <= 0)
{ {
@ -819,6 +821,7 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect,
} }
} }
} }
}
} }
return clipReturn; 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) 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; 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)); 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 // alignceilslope
// //

View file

@ -48,6 +48,7 @@ int32_t r_rortexturerange = 0;
int32_t r_rorphase = 0; int32_t r_rorphase = 0;
void calcSlope(const sectortype* sec, float xpos, float ypos, float* pceilz, float* pflorz);
int skiptile = -1; int skiptile = -1;
FGameTexture* GetSkyTexture(int basetile, int lognumtiles, const int16_t* tilemap, int remap = 0); 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 (have_floor)
{ {
if (globalposz > getflorzofslope(sectnum, globalposx, globalposy)) if (globalposz > getflorzofslopeptr(sec, globalposx, globalposy))
domostpolymethod = DAMETH_BACKFACECULL; //Back-face culling domostpolymethod = DAMETH_BACKFACECULL; //Back-face culling
if (domostpolymethod & DAMETH_MASKPROPS) if (domostpolymethod & DAMETH_MASKPROPS)
@ -1169,7 +1170,7 @@ static void polymost_internal_nonparallaxed(FVector2 n0, FVector2 n1, float ryp0
} }
else else
{ {
if (globalposz < getceilzofslope(sectnum, globalposx, globalposy)) if (globalposz < getceilzofslopeptr(sec, globalposx, globalposy))
domostpolymethod = DAMETH_BACKFACECULL; //Back-face culling domostpolymethod = DAMETH_BACKFACECULL; //Back-face culling
if (domostpolymethod & DAMETH_MASKPROPS) 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) static float fgetceilzofslope(usectorptr_t sec, float dax, float day)
{ {
if (!(sec->ceilingstat&2)) float z;
return float(sec->ceilingz); calcSlope(sec, dax, day, &z, nullptr);
return z;
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;
} }
static float fgetflorzofslope(usectorptr_t sec, float dax, float day) static float fgetflorzofslope(usectorptr_t sec, float dax, float day)
{ {
if (!(sec->floorstat&2)) float z;
return float(sec->floorz); calcSlope(sec, dax, day, nullptr, &z);
return z;
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;
} }
static void fgetzsofslope(usectorptr_t sec, float dax, float day, float* ceilz, float *florz) static void fgetzsofslope(usectorptr_t sec, float dax, float day, float* ceilz, float *florz)
{ {
*ceilz = float(sec->ceilingz); *florz = float(sec->floorz); calcSlope(sec, dax, day, ceilz, florz);
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;
} }
static void polymost_flatskyrender(FVector2 const* const dpxy, int32_t const n, int32_t method, const vec2_16_t &tilesize) 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)) else if (!(globalorientation&1))
{ {
int32_t fz = getflorzofslope(sectnum, globalposx, globalposy); int32_t fz = getflorzofslopeptr(sec, globalposx, globalposy);
if (globalposz <= fz) if (globalposz <= fz)
polymost_internal_nonparallaxed(n0, n1, ryp0, ryp1, x0, x1, fy0, fy1, sectnum, true); 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)) else if (!(globalorientation&1))
{ {
int32_t cz = getceilzofslope(sectnum, globalposx, globalposy); int32_t cz = getceilzofslopeptr(sec, globalposx, globalposy);
if (globalposz >= cz) if (globalposz >= cz)
polymost_internal_nonparallaxed(n0, n1, ryp0, ryp1, x0, x1, cy0, cy1, sectnum, false); 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 m0 = (int32_t)((wal2->x - wal->x) * t0 + wal->x);
int32_t m1 = (int32_t)((wal2->y - wal->y) * t0 + wal->y); int32_t m1 = (int32_t)((wal2->y - wal->y) * t0 + wal->y);
int32_t cz[4], fz[4]; 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]); getzsofslopeptr(wal->nextSector(), m0, m1, &cz[1], &fz[1]);
m0 = (int32_t)((wal2->x - wal->x) * t1 + wal->x); m0 = (int32_t)((wal2->x - wal->x) * t1 + wal->x);
m1 = (int32_t)((wal2->y - wal->y) * t1 + wal->y); 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]); getzsofslopeptr(wal->nextSector(), m0, m1, &cz[3], &fz[3]);
float ryp0 = 1.f/p0.Y; 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) void PlanesAtPoint(const sectortype* sec, int dax, int day, float* pceilz, float* pflorz)
{ {
float ceilz = float(sec->ceilingz); calcSlope(sec, dax, day, pceilz, pflorz);
float florz = float(sec->floorz); if (pceilz) *pceilz *= -(1 / 256.f);
if (pflorz) *pflorz *= -(1 / 256.f);
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);
} }
//==========================================================================
//
// 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 // Calculate the position of a wall sprite in the world

View file

@ -59,6 +59,14 @@ TArray<walltype> wall;
TArray<sectortype> sectorbackup; TArray<sectortype> sectorbackup;
TArray<walltype> wallbackup; 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. // needed for skipping over to get the map size first.
enum enum
{ {

View file

@ -334,6 +334,8 @@ struct walltype
int deltax() const { return point2Wall()->x - x; } int deltax() const { return point2Wall()->x - x; }
int deltay() const { return point2Wall()->y - y; } int deltay() const { return point2Wall()->y - y; }
bool twoSided() const { return nextsector >= 0; } 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 move(int newx, int newy);
void moved(); void moved();
@ -649,6 +651,16 @@ inline void walltype::move(int newx, int newy)
sectorp()->dirty = EDirty::AllDirty; sectorp()->dirty = EDirty::AllDirty;
} }
inline int walltype::Length()
{
if ((lengthflags & 1) || (point2Wall()->lengthflags & 2))
{
// value is stale, recreate
calcLength();
}
return length;
}
//============================================================================= //=============================================================================
// //
// Map loader stuff // Map loader stuff

View file

@ -19,7 +19,7 @@ void collectTSpritesForPortal(int x, int y, int i, int interpolation)
int top, bottom; int top, bottom;
GetSpriteExtents(pSprite, &top, &bottom); GetSpriteExtents(pSprite, &top, &bottom);
int zCeil, zFloor; 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)) if (pSprite->statnum == kStatDude && (top < zCeil || bottom > zFloor))
{ {
int j = i; int j = i;