mirror of
https://github.com/DrBeef/Raze.git
synced 2025-01-31 21:20:39 +00:00
- fixed updatesector and changed updatesectorz to use the same search algorithm.
The initial distance check in updatesectorneighbor had a far too low threshold which would skip the breadth-first search for relatively small distances already. Exhumed's LEV1 and Duke's Lunatic Fringe were the most obvious candidates where this could cause problems. Changed to use a mixture of the original updatesector with the revised algorithm so that all immediate neighbors of the start sector will get visited unconditionally. updatesectorz was still the original function from Shadow Warrior, this also was changed to use the same algorithm as uodatesector.
This commit is contained in:
parent
f765783437
commit
64cad55d73
3 changed files with 57 additions and 22 deletions
|
@ -439,7 +439,7 @@ int32_t try_facespr_intersect(uspriteptr_t const spr, vec3_t const in,
|
|||
vec3_t * const intp, int32_t strictly_smaller_than_p);
|
||||
|
||||
#define MAXUPDATESECTORDIST 1536
|
||||
#define INITIALUPDATESECTORDIST 256
|
||||
#define INITIALUPDATESECTORDIST 512 // was 256 which is too low - Exhumed LEV1 has problems with it
|
||||
void updatesector(int const x, int const y, int * const sectnum) ATTRIBUTE((nonnull(3)));
|
||||
inline void updatesector(int const x, int const y, sectortype** const sectp)
|
||||
{
|
||||
|
@ -449,8 +449,8 @@ inline void updatesector(int const x, int const y, sectortype** const sectp)
|
|||
}
|
||||
void updatesectorz(int32_t const x, int32_t const y, int32_t const z, int * const sectnum) ATTRIBUTE((nonnull(4)));
|
||||
|
||||
void updatesectorneighbor(int32_t const x, int32_t const y, int * const sectnum, int32_t initialMaxDistance = INITIALUPDATESECTORDIST, int32_t maxDistance = MAXUPDATESECTORDIST) ATTRIBUTE((nonnull(3)));
|
||||
void updatesectorneighborz(int32_t const x, int32_t const y, int32_t const z, int * const sectnum, int32_t initialMaxDistance = INITIALUPDATESECTORDIST, int32_t maxDistance = MAXUPDATESECTORDIST) ATTRIBUTE((nonnull(4)));
|
||||
void updatesectorneighbor(int32_t const x, int32_t const y, int * const sectnum, int32_t maxDistance = MAXUPDATESECTORDIST) ATTRIBUTE((nonnull(3)));
|
||||
void updatesectorneighborz(int32_t const x, int32_t const y, int32_t const z, int * const sectnum, int32_t maxDistance = MAXUPDATESECTORDIST) ATTRIBUTE((nonnull(4)));
|
||||
|
||||
int findwallbetweensectors(int sect1, int sect2);
|
||||
|
||||
|
|
|
@ -1184,7 +1184,8 @@ int findwallbetweensectors(int sect1, int sect2)
|
|||
void updatesector(int32_t const x, int32_t const y, int * const sectnum)
|
||||
{
|
||||
int sect = *sectnum;
|
||||
updatesectorneighbor(x, y, §, INITIALUPDATESECTORDIST, MAXUPDATESECTORDIST);
|
||||
|
||||
updatesectorneighbor(x, y, §, MAXUPDATESECTORDIST);
|
||||
if (sect != -1)
|
||||
SET_AND_RETURN(*sectnum, sect);
|
||||
|
||||
|
@ -1200,21 +1201,13 @@ void updatesector(int32_t const x, int32_t const y, int * const sectnum)
|
|||
|
||||
void updatesectorz(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);
|
||||
int sect = *sectnum;
|
||||
|
||||
updatesectorneighborz(x, y, z, §, MAXUPDATESECTORDIST);
|
||||
if (sect != -1)
|
||||
SET_AND_RETURN(*sectnum, sect);
|
||||
|
||||
walltype const * wal = &wall[sector[*sectnum].wallptr];
|
||||
int wallsleft = sector[*sectnum].wallnum;
|
||||
do
|
||||
{
|
||||
int const next = wal->nextsector;
|
||||
if (next>=0 && inside_z_p(x,y,z, next))
|
||||
SET_AND_RETURN(*sectnum, next);
|
||||
|
||||
wal++;
|
||||
}
|
||||
while (--wallsleft);
|
||||
|
||||
// we need to support passing in a sectnum of -1, unfortunately
|
||||
for (int i = numsectors - 1; i >= 0; --i)
|
||||
if (inside_z_p(x, y, z, i))
|
||||
|
@ -1223,17 +1216,18 @@ void updatesectorz(int32_t const x, int32_t const y, int32_t const z, int* const
|
|||
*sectnum = -1;
|
||||
}
|
||||
|
||||
void updatesectorneighbor(int32_t const x, int32_t const y, int * const sectnum, int32_t initialMaxDistance /*= INITIALUPDATESECTORDIST*/, int32_t maxDistance /*= MAXUPDATESECTORDIST*/)
|
||||
void updatesectorneighbor(int32_t const x, int32_t const y, int * const sectnum, int32_t maxDistance)
|
||||
{
|
||||
int const initialsectnum = *sectnum;
|
||||
|
||||
if ((validSectorIndex(initialsectnum)) && getsectordist({x, y}, initialsectnum) <= initialMaxDistance)
|
||||
if ((validSectorIndex(initialsectnum)))
|
||||
{
|
||||
if (inside_p(x, y, initialsectnum))
|
||||
return;
|
||||
|
||||
BFSSearch search(numsectors, *sectnum);
|
||||
|
||||
int iter = 0;
|
||||
for (unsigned listsectnum; (listsectnum = search.GetNext()) != BFSSearch::EOL;)
|
||||
{
|
||||
if (inside_p(x, y, listsectnum))
|
||||
|
@ -1244,9 +1238,42 @@ void updatesectorneighbor(int32_t const x, int32_t const y, int * const sectnum,
|
|||
|
||||
for (auto& wal : wallsofsector(listsectnum))
|
||||
{
|
||||
if (wal.nextsector >= 0 && getsectordist({ x, y }, wal.nextsector) <= maxDistance)
|
||||
if (wal.nextsector >= 0 && (iter == 0 || getsectordist({ x, y }, wal.nextsector) <= maxDistance))
|
||||
search.Add(wal.nextsector);
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
*sectnum = -1;
|
||||
}
|
||||
|
||||
void updatesectorneighborz(int32_t const x, int32_t const y, int32_t const z, int* const sectnum, int32_t maxDistance)
|
||||
{
|
||||
int const initialsectnum = *sectnum;
|
||||
|
||||
if ((validSectorIndex(initialsectnum)))
|
||||
{
|
||||
if (inside_z_p(x, y, z, initialsectnum))
|
||||
return;
|
||||
|
||||
BFSSearch search(numsectors, *sectnum);
|
||||
|
||||
int iter = 0;
|
||||
for (unsigned listsectnum; (listsectnum = search.GetNext()) != BFSSearch::EOL;)
|
||||
{
|
||||
if (inside_z_p(x, y, z, listsectnum))
|
||||
{
|
||||
*sectnum = listsectnum;
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& wal : wallsofsector(listsectnum))
|
||||
{
|
||||
if (wal.nextsector >= 0 && (iter == 0 || getsectordist({ x, y }, wal.nextsector) <= maxDistance))
|
||||
search.Add(wal.nextsector);
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1449,3 +1476,11 @@ int tilehasmodelorvoxel(int const tilenume, int pal)
|
|||
(mdinited && hw_models && tile2model[Ptile2tile(tilenume, pal)].modelid != -1) ||
|
||||
(r_voxels && tiletovox[tilenume] != -1);
|
||||
}
|
||||
|
||||
|
||||
CCMD(updatesectordebug)
|
||||
{
|
||||
int sect = 319;
|
||||
updatesector(1792, 24334, §);
|
||||
int blah = sect;
|
||||
}
|
|
@ -1108,7 +1108,7 @@ static void movetripbomb(DDukeActor *actor)
|
|||
int const oldSectNum = s->sectnum;
|
||||
int curSectNum = s->sectnum;
|
||||
|
||||
updatesectorneighbor(s->x, s->y, &curSectNum, 1024, 2048);
|
||||
updatesectorneighbor(s->x, s->y, &curSectNum, 2048);
|
||||
changeactorsect(actor, curSectNum);
|
||||
|
||||
DDukeActor* hit;
|
||||
|
@ -1139,7 +1139,7 @@ static void movetripbomb(DDukeActor *actor)
|
|||
|
||||
s->x += bcos(actor->temp_data[5], -4);
|
||||
s->y += bsin(actor->temp_data[5], -4);
|
||||
updatesectorneighbor(s->x, s->y, &curSectNum, 1024, 2048);
|
||||
updatesectorneighbor(s->x, s->y, &curSectNum, 2048);
|
||||
|
||||
if (curSectNum == -1)
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue