- added some helpers to make it easier to determine if a sector's geometry has been altered.

Walls had no sector reference so this was added for marking the sector as altered when a vertex gets dragged around.
This commit is contained in:
Christoph Oelckers 2021-03-19 20:40:44 +01:00
parent 895b875453
commit 3df5c440f9
10 changed files with 40 additions and 66 deletions

View file

@ -606,7 +606,6 @@ static FORCE_INLINE int32_t E_SpriteIsValid(const int32_t i)
void alignceilslope(int16_t dasect, int32_t x, int32_t y, int32_t z);
void alignflorslope(int16_t dasect, int32_t x, int32_t y, int32_t z);
int32_t sectorofwall(int16_t wallNum);
void setslope(int32_t sectnum, int32_t cf, int16_t slope);
int32_t lintersect(int32_t originX, int32_t originY, int32_t originZ,

View file

@ -51,6 +51,7 @@ struct sectortype
int16_t hitag;
int16_t extra;
uint8_t dirty;
float ceilingxpan_, ceilingypan_, floorxpan_, floorypan_;
int ceilingxpan() const { return int(ceilingxpan_); }
@ -91,7 +92,7 @@ struct walltype
};
vec2_t pos;
};
int16_t point2, nextwall, nextsector;
int16_t point2, nextwall, sector, nextsector;
uint16_t cstat;
int16_t picnum, overpicnum;
int8_t shade;

View file

@ -2323,6 +2323,7 @@ void dragpoint(int16_t pointhighlight, int32_t dax, int32_t day, uint8_t flags)
while (1)
{
sector[wall[w].sector].dirty = 255;
wall[w].x = dax;
wall[w].y = day;
walbitmap[w>>3] |= pow2char[w&7];
@ -2839,36 +2840,6 @@ void renderCompleteMirror(void)
}
//
// sectorofwall
//
static int32_t sectorofwall_internal(int16_t wallNum)
{
native_t gap = numsectors>>1, sectNum = gap;
while (gap > 1)
{
gap >>= 1;
native_t const n = !!(sector[sectNum].wallptr < wallNum);
sectNum += (n ^ (n - 1)) * gap;
}
while (sector[sectNum].wallptr > wallNum) sectNum--;
while (sector[sectNum].wallptr + sector[sectNum].wallnum <= wallNum) sectNum++;
return sectNum;
}
int32_t sectorofwall(int16_t wallNum)
{
if ((unsigned)wallNum < (unsigned)numwalls)
{
native_t const w = wall[wallNum].nextwall;
return ((unsigned)w < MAXWALLS) ? wall[w].nextsector : sectorofwall_internal(wallNum);
}
return -1;
}
int32_t getceilzofslopeptr(usectorptr_t sec, int32_t dax, int32_t day)
{
if (!(sec->ceilingstat&2))

View file

@ -175,7 +175,7 @@ bool spriteIsModelOrVoxel(const spritetype * tspr)
//
//==========================================================================
void PlanesAtPoint(usectorptr_t sec, float dax, float day, float* pceilz, float* pflorz)
void PlanesAtPoint(const sectortype* sec, float dax, float day, float* pceilz, float* pflorz)
{
float ceilz = float(sec->ceilingz);
float florz = float(sec->floorz);
@ -200,25 +200,3 @@ void PlanesAtPoint(usectorptr_t sec, float dax, float day, float* pceilz, float*
if (pceilz) *pceilz = ceilz * -(1.f / 256.f);
if (pflorz) *pflorz = florz * -(1.f / 256.f);
}
// variant that allows to pass precalculated info for the first line in. For cases where multiple points in a sector need to be checked.
void PlanesAtPoint(usectorptr_t sec, PlaneParam *pp, float dax, float 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)
{
if (pp->length != 0)
{
auto wal = &wall[sec->wallptr];
float const j = (pp->dx * (day - wal->y) - pp->dy * (dax - wal->x)) * (1.f / 8.f);
if (sec->ceilingstat & CSTAT_SECTOR_SLOPE) ceilz += (sec->ceilingheinum * j) / pp->length;
if (sec->floorstat & CSTAT_SECTOR_SLOPE) florz += (sec->floorheinum * j) / pp->length;
}
}
// Scale to render coordinates.
if (pceilz) *pceilz = ceilz * -(1.f / 256.f);
if (pflorz) *pflorz = florz * -(1.f / 256.f);
}

View file

@ -8,15 +8,8 @@ extern int cameradist, cameraclock;
bool calcChaseCamPos(int* px, int* py, int* pz, spritetype* pspr, short *psectnum, binangle ang, fixedhoriz horiz, double const smoothratio);
bool spriteIsModelOrVoxel(const spritetype* tspr);
void PlanesAtPoint(usectorptr_t sec, float dax, float day, float* ceilz, float* florz);
struct PlaneParam
{
float dx, dy;
int length;
};
void PlanesAtPoint(usectorptr_t sec, PlaneParam* pp, float dax, float day, float* ceilz, float* florz);
void PlanesAtPoint(const sectortype* sec, float dax, float day, float* ceilz, float* florz);
void setWallSectors();
// 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!
@ -76,3 +69,10 @@ inline double PointOnLineSide(double x, double y, double linex, double liney, do
return (x - linex) * deltay - (y - liney) * deltax;
}
inline int sectorofwall(int wallNum)
{
if ((unsigned)wallNum < (unsigned)numwalls) return wall[wallNum].sector;
return -1;
}

View file

@ -72,8 +72,8 @@ void Set(int index, int type, double val)
case Interp_Sect_CeilingPanX: sector[index].ceilingxpan_ = float(val); break;
case Interp_Sect_CeilingPanY: sector[index].ceilingypan_ = float(val); break;
case Interp_Wall_X: wall[index].x = xs_CRoundToInt(val); break;
case Interp_Wall_Y: wall[index].y = xs_CRoundToInt(val); break;
case Interp_Wall_X: wall[index].x = xs_CRoundToInt(val); sector[wall[index].sector].dirty = 255; break;
case Interp_Wall_Y: wall[index].y = xs_CRoundToInt(val); sector[wall[index].sector].dirty = 255; break;
case Interp_Wall_PanX: wall[index].xpan_ = float(val); break;
case Interp_Wall_PanY: wall[index].ypan_ = float(val); break;

View file

@ -41,6 +41,7 @@
#include "inputstate.h"
#include "md4.h"
#include "gamecontrol.h"
#include "gamefuncs.h"
static void ReadSectorV7(FileReader& fr, sectortype& sect)
@ -444,6 +445,7 @@ void engineLoadBoard(const char* filename, int flags, vec3_t* pos, int16_t* ang,
unsigned char md4[16];
md4once(buffer.Data(), buffer.Size(), md4);
G_LoadMapHack(filename, md4);
setWallSectors();
memcpy(wallbackup, wall, sizeof(wallbackup));
memcpy(sectorbackup, sector, sizeof(sectorbackup));
@ -468,4 +470,17 @@ void loadMapBackup(const char* filename)
engineLoadBoard(filename, 0, &pos, &scratch, &scratch);
initspritelists();
}
}
// Sets the sector reference for each wall. We need this for the triangulation cache.
void setWallSectors()
{
for (int i = 0; i < numsectors; i++)
{
sector[i].dirty = 255;
for (int w = 0; w < sector[i].wallnum; w++)
{
wall[sector[i].wallptr + w].sector = i;
}
}
}

View file

@ -56,6 +56,7 @@
#include "gamestate.h"
#include "razemenu.h"
#include "interpolate.h"
#include "gamefuncs.h"
sectortype sectorbackup[MAXSECTORS];
@ -670,6 +671,10 @@ void SerializeMap(FSerializer& arc)
if (prevspritestat[i] == -2) prevspritestat[i] = i - 1;
if (prevspritesect[i] == -2) prevspritesect[i] = i - 1;
}
if (arc.isReading())
{
setWallSectors();
}
}
//=============================================================================

View file

@ -31,6 +31,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "md4.h"
#include "automap.h"
#include "raze_sound.h"
#include "gamefuncs.h"
#include "blood.h"
@ -1058,6 +1059,7 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor
}
}
setWallSectors();
memcpy(wallbackup, wall, sizeof(wallbackup));
memcpy(sectorbackup, sector, sizeof(sectorbackup));
}

View file

@ -794,6 +794,7 @@ void PathSound(int nSector, int nSound)
void DragPoint(int nWall, int x, int y)
{
sector[wall[nWall].sector].dirty = 255;
viewInterpolateWall(nWall, &wall[nWall]);
wall[nWall].x = x;
wall[nWall].y = y;
@ -805,6 +806,7 @@ void DragPoint(int nWall, int x, int y)
if (wall[vb].nextwall >= 0)
{
vb = wall[wall[vb].nextwall].point2;
sector[wall[vb].sector].dirty = 255;
viewInterpolateWall(vb, &wall[vb]);
wall[vb].x = x;
wall[vb].y = y;
@ -817,6 +819,7 @@ void DragPoint(int nWall, int x, int y)
if (wall[lastwall(vb)].nextwall >= 0)
{
vb = wall[lastwall(vb)].nextwall;
sector[wall[vb].sector].dirty = 255;
viewInterpolateWall(vb, &wall[vb]);
wall[vb].x = x;
wall[vb].y = y;