mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-26 03:30:46 +00:00
This should fix updatesector/updatesectorz performance while retaining the benefits of breadth-first search
git-svn-id: https://svn.eduke32.com/eduke32@7601 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
a89c260592
commit
ab857c4e8f
2 changed files with 127 additions and 126 deletions
|
@ -908,51 +908,58 @@ static int32_t get_floorspr_clipyou(int32_t x1, int32_t x2, int32_t x3, int32_t
|
||||||
return clipyou;
|
return clipyou;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clipupdatesector(vec2_t const &p, int16_t * const sectnum, int const walldist)
|
static void clipupdatesector(vec2_t const &pos, int16_t * const sectnum, int const walldist)
|
||||||
{
|
{
|
||||||
if (inside_p(p.x, p.y, *sectnum))
|
if (inside_p(pos.x, pos.y, *sectnum))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
static int16_t sectlist[MAXSECTORS];
|
static int16_t sectlist[MAXSECTORS];
|
||||||
static uint8_t sectbitmap[(MAXSECTORS+7)>>3];
|
static uint8_t sectbitmap[(MAXSECTORS+7)>>3];
|
||||||
int32_t nsecs;
|
int32_t nsecs;
|
||||||
|
|
||||||
bfirst_search_init(sectlist, sectbitmap, &nsecs, numsectors, *sectnum);
|
bfirst_search_init(sectlist, sectbitmap, &nsecs, MAXCLIPSECTORS, *sectnum);
|
||||||
|
|
||||||
for (int sectcnt = 0; sectcnt < nsecs; sectcnt++)
|
for (int sectcnt = 0; sectcnt < nsecs; sectcnt++)
|
||||||
{
|
{
|
||||||
if (inside_p(p.x, p.y, sectlist[sectcnt]))
|
int const listsectnum = sectlist[sectcnt];
|
||||||
SET_AND_RETURN(*sectnum, sectlist[sectcnt]);
|
|
||||||
|
|
||||||
auto const sec = §or[sectlist[sectcnt]];
|
if (inside_p(pos.x, pos.y, listsectnum))
|
||||||
|
SET_AND_RETURN(*sectnum, listsectnum);
|
||||||
|
|
||||||
|
auto const sec = §or[listsectnum];
|
||||||
int const startwall = sec->wallptr;
|
int const startwall = sec->wallptr;
|
||||||
int const endwall = sec->wallptr + sec->wallnum;
|
int const endwall = sec->wallptr + sec->wallnum;
|
||||||
|
auto uwal = (uwalltype *)&wall[startwall];
|
||||||
|
|
||||||
for (int j = startwall; j < endwall; j++)
|
for (int j = startwall; j < endwall; j++, uwal++)
|
||||||
if (wall[j].nextsector >= 0 && bitmap_test(clipsectormap, wall[j].nextsector))
|
if (uwal->nextsector >= 0 && bitmap_test(clipsectormap, uwal->nextsector))
|
||||||
bfirst_search_try(sectlist, sectbitmap, &nsecs, wall[j].nextsector);
|
bfirst_search_try(sectlist, sectbitmap, &nsecs, uwal->nextsector);
|
||||||
}
|
}
|
||||||
|
|
||||||
bfirst_search_init(sectlist, sectbitmap, &nsecs, numsectors, *sectnum);
|
bfirst_search_init(sectlist, sectbitmap, &nsecs, MAXSECTORS, *sectnum);
|
||||||
|
|
||||||
for (int sectcnt = 0; sectcnt < nsecs; sectcnt++)
|
for (int sectcnt = 0; sectcnt < nsecs; sectcnt++)
|
||||||
{
|
{
|
||||||
if (inside_p(p.x, p.y, sectlist[sectcnt]))
|
int const listsectnum = sectlist[sectcnt];
|
||||||
|
|
||||||
|
if (inside_p(pos.x, pos.y, listsectnum))
|
||||||
{
|
{
|
||||||
// add sector to clipping list so the next call to clipupdatesector()
|
// add sector to clipping list so the next call to clipupdatesector()
|
||||||
// finishes in the loop above this one
|
// finishes in the loop above this one
|
||||||
addclipsect(sectlist[sectcnt]);
|
addclipsect(listsectnum);
|
||||||
SET_AND_RETURN(*sectnum, sectlist[sectcnt]);
|
SET_AND_RETURN(*sectnum, listsectnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const sec = §or[sectlist[sectcnt]];
|
auto const sec = §or[listsectnum];
|
||||||
int const startwall = sec->wallptr;
|
int const startwall = sec->wallptr;
|
||||||
int const endwall = sec->wallptr + sec->wallnum;
|
int const endwall = sec->wallptr + sec->wallnum;
|
||||||
|
auto uwal = (uwalltype *)&wall[startwall];
|
||||||
|
|
||||||
// check floor curbs here?
|
// check floor curbs here?
|
||||||
for (int j = startwall; j < endwall; j++)
|
|
||||||
if (wall[j].nextsector >= 0 && getwalldist(p, j) <= walldist)
|
for (int j = startwall; j < endwall; j++, uwal++)
|
||||||
bfirst_search_try(sectlist, sectbitmap, &nsecs, wall[j].nextsector);
|
if (uwal->nextsector >= 0 && getwalldist(pos, j) <= walldist)
|
||||||
|
bfirst_search_try(sectlist, sectbitmap, &nsecs, uwal->nextsector);
|
||||||
}
|
}
|
||||||
|
|
||||||
*sectnum = -1;
|
*sectnum = -1;
|
||||||
|
|
|
@ -10621,37 +10621,32 @@ void get_floorspr_points(uspritetype const * const spr, int32_t px, int32_t py,
|
||||||
int32_t *y1, int32_t *y2, int32_t *y3, int32_t *y4)
|
int32_t *y1, int32_t *y2, int32_t *y3, int32_t *y4)
|
||||||
{
|
{
|
||||||
const int32_t tilenum = spr->picnum;
|
const int32_t tilenum = spr->picnum;
|
||||||
// &2047 in sinang:
|
|
||||||
// DNE 1.3D lights camera action (1st level), spr->ang==2306
|
|
||||||
// (probably from CON)
|
|
||||||
const int32_t cosang = sintable[(spr->ang+512)&2047];
|
const int32_t cosang = sintable[(spr->ang+512)&2047];
|
||||||
const int32_t sinang = sintable[spr->ang&2047];
|
const int32_t sinang = sintable[spr->ang&2047];
|
||||||
|
|
||||||
const int32_t xspan=tilesiz[tilenum].x, xrepeat=spr->xrepeat;
|
vec2_t const span = { tilesiz[tilenum].x, tilesiz[tilenum].y};
|
||||||
const int32_t yspan=tilesiz[tilenum].y, yrepeat=spr->yrepeat;
|
vec2_t const repeat = { spr->xrepeat, spr->yrepeat };
|
||||||
|
|
||||||
int32_t xoff = picanm[tilenum].xofs + spr->xoffset;
|
vec2_t adjofs = { picanm[tilenum].xofs + spr->xoffset, picanm[tilenum].yofs + spr->yoffset };
|
||||||
int32_t yoff = picanm[tilenum].yofs + spr->yoffset;
|
|
||||||
int32_t k, l, dax, day;
|
|
||||||
|
|
||||||
if (spr->cstat&4)
|
if (spr->cstat & 4)
|
||||||
xoff = -xoff;
|
adjofs.x = -adjofs.x;
|
||||||
if (spr->cstat&8)
|
|
||||||
yoff = -yoff;
|
|
||||||
|
|
||||||
dax = ((xspan>>1)+xoff)*xrepeat;
|
if (spr->cstat & 8)
|
||||||
day = ((yspan>>1)+yoff)*yrepeat;
|
adjofs.y = -adjofs.y;
|
||||||
|
|
||||||
*x1 += dmulscale16(sinang,dax, cosang,day) - px;
|
vec2_t const center = { ((span.x >> 1) + adjofs.x) * repeat.x, ((span.y >> 1) + adjofs.y) * repeat.y };
|
||||||
*y1 += dmulscale16(sinang,day, -cosang,dax) - py;
|
vec2_t const rspan = { span.x * repeat.x, span.y * repeat.y };
|
||||||
|
vec2_t const ofs = { -mulscale16(cosang, rspan.y), -mulscale16(sinang, rspan.y) };
|
||||||
|
|
||||||
l = xspan*xrepeat;
|
*x1 += dmulscale16(sinang, center.x, cosang, center.y) - px;
|
||||||
*x2 = *x1 - mulscale16(sinang,l);
|
*y1 += dmulscale16(sinang, center.y, -cosang, center.x) - py;
|
||||||
*y2 = *y1 + mulscale16(cosang,l);
|
|
||||||
|
|
||||||
l = yspan*yrepeat;
|
*x2 = *x1 - mulscale16(sinang, rspan.x);
|
||||||
k = -mulscale16(cosang,l); *x3 = *x2+k; *x4 = *x1+k;
|
*y2 = *y1 + mulscale16(cosang, rspan.x);
|
||||||
k = -mulscale16(sinang,l); *y3 = *y2+k; *y4 = *y1+k;
|
|
||||||
|
*x3 = *x2 + ofs.x, *x4 = *x1 + ofs.x;
|
||||||
|
*y3 = *y2 + ofs.y, *y4 = *y1 + ofs.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -10971,17 +10966,17 @@ static inline bool inside_z_p(int32_t const x, int32_t const y, int32_t const z,
|
||||||
return (z >= cz && z <= fz && inside_p(x, y, sectnum));
|
return (z >= cz && z <= fz && inside_p(x, y, sectnum));
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t getwalldist(vec2_t const &p, int const wallnum, vec2_t * const output)
|
int32_t getwalldist(vec2_t const &pos, int const wallnum, vec2_t * const output)
|
||||||
{
|
{
|
||||||
vec2_t closest;
|
vec2_t closest;
|
||||||
getclosestpointonwall_internal(p, wallnum, &closest);
|
getclosestpointonwall_internal(pos, wallnum, &closest);
|
||||||
if (output) *output = closest;
|
if (output) *output = closest;
|
||||||
return klabs(closest.x - p.x) + klabs(closest.y - p.y);
|
return klabs(closest.x - pos.x) + klabs(closest.y - pos.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t getsectordist(vec2_t const &p, int const sectnum)
|
int32_t getsectordist(vec2_t const &pos, int const sectnum)
|
||||||
{
|
{
|
||||||
if (inside_p(p.x, p.y, sectnum))
|
if (inside_p(pos.x, pos.y, sectnum))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int32_t distance = INT32_MAX;
|
int32_t distance = INT32_MAX;
|
||||||
|
@ -10993,7 +10988,7 @@ int32_t getsectordist(vec2_t const &p, int const sectnum)
|
||||||
|
|
||||||
for (int j = startwall; j < endwall; j++, uwal++)
|
for (int j = startwall; j < endwall; j++, uwal++)
|
||||||
{
|
{
|
||||||
int32_t const walldist = getwalldist(p, j);
|
int32_t const walldist = getwalldist(pos, j);
|
||||||
distance = min(walldist, distance);
|
distance = min(walldist, distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11012,45 +11007,50 @@ bool sectoradjacent(int sect1, int sect2)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MAXUPDATESECTORDIST 1536
|
||||||
|
#define INITIALUPDATESECTORDIST 256
|
||||||
|
|
||||||
//
|
//
|
||||||
// updatesector[z]
|
// updatesector[z]
|
||||||
//
|
//
|
||||||
void updatesector(int32_t const x, int32_t const y, int16_t * const sectnum)
|
void updatesector(int32_t const x, int32_t const y, int16_t * const sectnum)
|
||||||
{
|
{
|
||||||
if (inside_p(x, y, *sectnum))
|
int const initialsectnum = *sectnum;
|
||||||
return;
|
|
||||||
|
|
||||||
if ((unsigned)*sectnum >= (unsigned)numsectors)
|
if ((unsigned)initialsectnum < (unsigned)numsectors && getsectordist({x, y}, initialsectnum) < INITIALUPDATESECTORDIST)
|
||||||
{
|
{
|
||||||
// we need to support passing in a sectnum of -1, unfortunately
|
if (inside_p(x, y, initialsectnum))
|
||||||
|
return;
|
||||||
for (int i = numsectors - 1; i >= 0; --i)
|
|
||||||
if (inside_p(x, y, i))
|
|
||||||
SET_AND_RETURN(*sectnum, i);
|
|
||||||
|
|
||||||
SET_AND_RETURN(*sectnum, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int16_t sectlist[MAXSECTORS];
|
static int16_t sectlist[MAXSECTORS];
|
||||||
static uint8_t sectbitmap[(MAXSECTORS+7)>>3];
|
static uint8_t sectbitmap[(MAXSECTORS+7)>>3];
|
||||||
int32_t nsecs;
|
int32_t nsecs;
|
||||||
|
|
||||||
bfirst_search_init(sectlist, sectbitmap, &nsecs, numsectors, *sectnum);
|
bfirst_search_init(sectlist, sectbitmap, &nsecs, MAXSECTORS, initialsectnum);
|
||||||
|
|
||||||
for (int sectcnt=0; sectcnt<nsecs; sectcnt++)
|
for (int sectcnt=0; sectcnt<nsecs; sectcnt++)
|
||||||
{
|
{
|
||||||
if (inside_p(x, y, sectlist[sectcnt]))
|
int const listsectnum = sectlist[sectcnt];
|
||||||
SET_AND_RETURN(*sectnum, sectlist[sectcnt]);
|
|
||||||
|
|
||||||
auto const sec = §or[sectlist[sectcnt]];
|
if (inside_p(x, y, listsectnum))
|
||||||
|
SET_AND_RETURN(*sectnum, listsectnum);
|
||||||
|
|
||||||
|
auto const sec = §or[listsectnum];
|
||||||
int const startwall = sec->wallptr;
|
int const startwall = sec->wallptr;
|
||||||
int const endwall = sec->wallptr + sec->wallnum;
|
int const endwall = sec->wallptr + sec->wallnum;
|
||||||
|
auto uwal = (uwalltype *)&wall[startwall];
|
||||||
|
|
||||||
for (int j=startwall; j<endwall; j++)
|
for (int j=startwall; j<endwall; j++, uwal++)
|
||||||
if (wall[j].nextsector >= 0)
|
if (uwal->nextsector >= 0 && getsectordist({x, y}, uwal->nextsector) < MAXUPDATESECTORDIST)
|
||||||
bfirst_search_try(sectlist, sectbitmap, &nsecs, wall[j].nextsector);
|
bfirst_search_try(sectlist, sectbitmap, &nsecs, uwal->nextsector);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we need to support passing in a sectnum of -1, unfortunately
|
||||||
|
|
||||||
|
for (int i = numsectors - 1; i >= 0; --i)
|
||||||
|
if (inside_p(x, y, i))
|
||||||
|
SET_AND_RETURN(*sectnum, i);
|
||||||
|
|
||||||
*sectnum = -1;
|
*sectnum = -1;
|
||||||
}
|
}
|
||||||
|
@ -11090,74 +11090,68 @@ void updatesectorz(int32_t const x, int32_t const y, int32_t const z, int16_t *
|
||||||
{
|
{
|
||||||
bool nofirstzcheck = false;
|
bool nofirstzcheck = false;
|
||||||
|
|
||||||
if ((unsigned)*sectnum >= (unsigned)numsectors)
|
|
||||||
{
|
|
||||||
if (*sectnum >= MAXSECTORS && (unsigned)*sectnum < (unsigned)numsectors + MAXSECTORS)
|
if (*sectnum >= MAXSECTORS && (unsigned)*sectnum < (unsigned)numsectors + MAXSECTORS)
|
||||||
{
|
{
|
||||||
*sectnum -= MAXSECTORS;
|
*sectnum -= MAXSECTORS;
|
||||||
nofirstzcheck = true;
|
nofirstzcheck = true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
int const correctedsectnum = *sectnum;
|
||||||
|
|
||||||
|
if ((unsigned)correctedsectnum < (unsigned)numsectors && getsectordist({x, y}, correctedsectnum) < INITIALUPDATESECTORDIST)
|
||||||
{
|
{
|
||||||
// we need to support passing in a sectnum of -1, unfortunately
|
if (nofirstzcheck && inside_p(x, y, correctedsectnum))
|
||||||
for (int i = numsectors - 1; i >= 0; --i)
|
return;
|
||||||
if (inside_z_p(x, y, z, i))
|
|
||||||
SET_AND_RETURN(*sectnum, i);
|
|
||||||
|
|
||||||
for (int i = numsectors - 1; i >= 0; --i)
|
|
||||||
if (inside_p(x, y, i))
|
|
||||||
SET_AND_RETURN(*sectnum, i);
|
|
||||||
|
|
||||||
SET_AND_RETURN(*sectnum, -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t cz, fz;
|
int32_t cz, fz;
|
||||||
getzsofslope(*sectnum, x, y, &cz, &fz);
|
getzsofslope(correctedsectnum, x, y, &cz, &fz);
|
||||||
|
|
||||||
#ifdef YAX_ENABLE
|
#ifdef YAX_ENABLE
|
||||||
if (z < cz)
|
if (z < cz)
|
||||||
{
|
{
|
||||||
int const next = yax_getneighborsect(x, y, *sectnum, YAX_CEILING);
|
int const next = yax_getneighborsect(x, y, correctedsectnum, YAX_CEILING);
|
||||||
if (next >= 0 && z >= getceilzofslope(next, x, y))
|
if (next >= 0 && z >= getceilzofslope(next, x, y))
|
||||||
SET_AND_RETURN(*sectnum, next);
|
SET_AND_RETURN(*sectnum, next);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (z > fz)
|
if (z > fz)
|
||||||
{
|
{
|
||||||
int const next = yax_getneighborsect(x, y, *sectnum, YAX_FLOOR);
|
int const next = yax_getneighborsect(x, y, correctedsectnum, YAX_FLOOR);
|
||||||
if (next >= 0 && z <= getflorzofslope(next, x, y))
|
if (next >= 0 && z <= getflorzofslope(next, x, y))
|
||||||
SET_AND_RETURN(*sectnum, next);
|
SET_AND_RETURN(*sectnum, next);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (nofirstzcheck || (z >= cz && z <= fz))
|
if (z >= cz && z <= fz && inside_p(x, y, correctedsectnum))
|
||||||
if (inside_p(x, y, *sectnum))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
static int16_t sectlist[MAXSECTORS];
|
static int16_t sectlist[MAXSECTORS];
|
||||||
static uint8_t sectbitmap[(MAXSECTORS+7)>>3];
|
static uint8_t sectbitmap[(MAXSECTORS+7)>>3];
|
||||||
int32_t nsecs;
|
int32_t nsecs;
|
||||||
|
|
||||||
bfirst_search_init(sectlist, sectbitmap, &nsecs, numsectors, *sectnum);
|
bfirst_search_init(sectlist, sectbitmap, &nsecs, MAXSECTORS, correctedsectnum);
|
||||||
|
|
||||||
for (int sectcnt=0; sectcnt<nsecs; sectcnt++)
|
for (int sectcnt=0; sectcnt<nsecs; sectcnt++)
|
||||||
{
|
{
|
||||||
if (inside_z_p(x, y, z, sectlist[sectcnt]))
|
int const listsectnum = sectlist[sectcnt];
|
||||||
SET_AND_RETURN(*sectnum, sectlist[sectcnt]);
|
|
||||||
|
|
||||||
auto const sec = §or[sectlist[sectcnt]];
|
if (inside_z_p(x, y, z, listsectnum))
|
||||||
|
SET_AND_RETURN(*sectnum, listsectnum);
|
||||||
|
|
||||||
|
auto const sec = §or[listsectnum];
|
||||||
int const startwall = sec->wallptr;
|
int const startwall = sec->wallptr;
|
||||||
int const endwall = sec->wallptr + sec->wallnum;
|
int const endwall = sec->wallptr + sec->wallnum;
|
||||||
|
auto uwal = (uwalltype *)&wall[startwall];
|
||||||
|
|
||||||
for (int j=startwall; j<endwall; j++)
|
for (int j=startwall; j<endwall; j++, uwal++)
|
||||||
if (wall[j].nextsector >= 0)
|
if (uwal->nextsector >= 0 && getsectordist({x, y}, uwal->nextsector) < MAXUPDATESECTORDIST)
|
||||||
bfirst_search_try(sectlist, sectbitmap, &nsecs, wall[j].nextsector);
|
bfirst_search_try(sectlist, sectbitmap, &nsecs, uwal->nextsector);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fall back to searching without z... this is really a bullshit worst case scenario
|
// we need to support passing in a sectnum of -1, unfortunately
|
||||||
for (int sectcnt=0; sectcnt<nsecs; sectcnt++)
|
for (int i = numsectors - 1; i >= 0; --i)
|
||||||
if (inside_p(x, y, sectlist[sectcnt]))
|
if (inside_z_p(x, y, z, i))
|
||||||
SET_AND_RETURN(*sectnum, sectlist[sectcnt]);
|
SET_AND_RETURN(*sectnum, i);
|
||||||
|
|
||||||
*sectnum = -1;
|
*sectnum = -1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue