mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-11-10 23:02:03 +00:00
Add updatesectorneighbour() and updatesectorneighbourz() and make them accessible to CON to allow searching for nearby neighbouring sectors from a known sector.
These updatesector counterparts are more performant for tasks that require determining whether nearby sectors exist at a point as they will not exhaustively search the map. This also leads to more correct behaviour when sectors are disjoint, as queries will breadth-first search neighbouring sectors rather than risk accidentally stumbling first across accomodating disjoint sectors. git-svn-id: https://svn.eduke32.com/eduke32@7805 1a8010ca-5511-0410-912e-c29ae57300e0 # Conflicts: # source/build/include/build.h
This commit is contained in:
parent
844ec0bd63
commit
3d63d1b720
8 changed files with 131 additions and 52 deletions
|
@ -1169,14 +1169,6 @@ void neartag(int32_t xs, int32_t ys, int32_t zs, int16_t sectnum, int16_t ange
|
|||
int32_t (*blacklist_sprite_func)(int32_t)) ATTRIBUTE((nonnull(6,7,8)));
|
||||
int32_t cansee(int32_t x1, int32_t y1, int32_t z1, int16_t sect1,
|
||||
int32_t x2, int32_t y2, int32_t z2, int16_t sect2);
|
||||
void updatesector(int32_t const x, int32_t const y, int16_t * const sectnum) ATTRIBUTE((nonnull(3)));
|
||||
inline void updatesectorbreadth(int32_t const x, int32_t const y, int16_t *sectnum) ATTRIBUTE((nonnull(3)))
|
||||
{
|
||||
updatesector(x, y, sectnum);
|
||||
}
|
||||
void updatesectorexclude(int32_t const x, int32_t const y, int16_t * const sectnum,
|
||||
const uint8_t * const excludesectbitmap) ATTRIBUTE((nonnull(3,4)));
|
||||
void updatesectorz(int32_t const x, int32_t const y, int32_t const z, int16_t * const sectnum) ATTRIBUTE((nonnull(4)));
|
||||
int32_t inside(int32_t x, int32_t y, int16_t sectnum);
|
||||
void dragpoint(int16_t pointhighlight, int32_t dax, int32_t day, uint8_t flags);
|
||||
void setfirstwall(int16_t sectnum, int16_t newfirstwall);
|
||||
|
@ -1184,6 +1176,15 @@ int32_t try_facespr_intersect(uspriteptr_t const spr, const vec3_t *refpos,
|
|||
int32_t vx, int32_t vy, int32_t vz,
|
||||
vec3_t *intp, int32_t strictly_smaller_than_p);
|
||||
|
||||
#define MAXUPDATESECTORDIST 1536
|
||||
#define INITIALUPDATESECTORDIST 256
|
||||
void updatesector(int32_t const x, int32_t const y, int16_t * const sectnum) ATTRIBUTE((nonnull(3)));
|
||||
void updatesectorexclude(int32_t const x, int32_t const y, int16_t * const sectnum,
|
||||
const uint8_t * const excludesectbitmap) ATTRIBUTE((nonnull(3,4)));
|
||||
void updatesectorz(int32_t const x, int32_t const y, int32_t const z, int16_t * const sectnum) ATTRIBUTE((nonnull(4)));
|
||||
void updatesectorneighbour(int32_t const x, int32_t const y, int16_t * const sectnum, int32_t initialMaxDistance = INITIALUPDATESECTORDIST, int32_t maxDistance = MAXUPDATESECTORDIST) ATTRIBUTE((nonnull(3)));
|
||||
void updatesectorneighbourz(int32_t const x, int32_t const y, int32_t const z, int16_t * const sectnum, int32_t initialMaxDistance = INITIALUPDATESECTORDIST, int32_t maxDistance = MAXUPDATESECTORDIST) ATTRIBUTE((nonnull(4)));
|
||||
|
||||
int findwallbetweensectors(int sect1, int sect2);
|
||||
static FORCE_INLINE bool sectoradjacent(int sect1, int sect2) { return findwallbetweensectors(sect1, sect2) != -1; }
|
||||
int32_t getwalldist(vec2_t const &in, int const wallnum, vec2_t * const out = nullptr);
|
||||
|
|
|
@ -11407,44 +11407,15 @@ int findwallbetweensectors(int sect1, int sect2)
|
|||
return -1;
|
||||
}
|
||||
|
||||
#define MAXUPDATESECTORDIST 1536
|
||||
#define INITIALUPDATESECTORDIST 256
|
||||
|
||||
//
|
||||
// updatesector[z]
|
||||
//
|
||||
void updatesector(int32_t const x, int32_t const y, int16_t * const sectnum)
|
||||
{
|
||||
int const initialsectnum = *sectnum;
|
||||
|
||||
if ((unsigned)initialsectnum < (unsigned)numsectors && getsectordist({x, y}, initialsectnum) < INITIALUPDATESECTORDIST)
|
||||
{
|
||||
if (inside_p(x, y, initialsectnum))
|
||||
return;
|
||||
|
||||
static int16_t sectlist[MAXSECTORS];
|
||||
static uint8_t sectbitmap[(MAXSECTORS+7)>>3];
|
||||
int16_t nsecs;
|
||||
|
||||
bfirst_search_init(sectlist, sectbitmap, &nsecs, MAXSECTORS, initialsectnum);
|
||||
|
||||
for (int sectcnt=0; sectcnt<nsecs; sectcnt++)
|
||||
{
|
||||
int const listsectnum = 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 endwall = sec->wallptr + sec->wallnum;
|
||||
auto uwal = (uwallptr_t)&wall[startwall];
|
||||
|
||||
for (int j=startwall; j<endwall; j++, uwal++)
|
||||
if (uwal->nextsector >= 0 && getsectordist({x, y}, uwal->nextsector) < MAXUPDATESECTORDIST)
|
||||
bfirst_search_try(sectlist, sectbitmap, &nsecs, uwal->nextsector);
|
||||
}
|
||||
}
|
||||
int16_t sect = *sectnum;
|
||||
updatesectorneighbour(x, y, §, INITIALUPDATESECTORDIST, MAXUPDATESECTORDIST);
|
||||
if (sect != -1)
|
||||
SET_AND_RETURN(*sectnum, sect);
|
||||
|
||||
// we need to support passing in a sectnum of -1, unfortunately
|
||||
|
||||
|
@ -11487,6 +11458,57 @@ void updatesectorexclude(int32_t const x, int32_t const y, int16_t * const sectn
|
|||
// (not initial anymore because it follows the sector updating due to TROR)
|
||||
|
||||
void updatesectorz(int32_t const x, int32_t const y, int32_t const z, int16_t * const sectnum)
|
||||
{
|
||||
int16_t sect = *sectnum;
|
||||
updatesectorneighbourz(x, y, z, §, INITIALUPDATESECTORDIST, MAXUPDATESECTORDIST);
|
||||
if (sect != -1)
|
||||
SET_AND_RETURN(*sectnum, sect);
|
||||
|
||||
// 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))
|
||||
SET_AND_RETURN(*sectnum, i);
|
||||
|
||||
*sectnum = -1;
|
||||
}
|
||||
|
||||
void updatesectorneighbour(int32_t const x, int32_t const y, int16_t * const sectnum, int32_t initialMaxDistance /*= INITIALUPDATESECTORDIST*/, int32_t maxDistance /*= MAXUPDATESECTORDIST*/)
|
||||
{
|
||||
int const initialsectnum = *sectnum;
|
||||
|
||||
if ((unsigned)initialsectnum < (unsigned)numsectors && getsectordist({x, y}, initialsectnum) <= initialMaxDistance)
|
||||
{
|
||||
if (inside_p(x, y, initialsectnum))
|
||||
return;
|
||||
|
||||
static int16_t sectlist[MAXSECTORS];
|
||||
static uint8_t sectbitmap[(MAXSECTORS+7)>>3];
|
||||
int16_t nsecs;
|
||||
|
||||
bfirst_search_init(sectlist, sectbitmap, &nsecs, MAXSECTORS, initialsectnum);
|
||||
|
||||
for (int sectcnt=0; sectcnt<nsecs; sectcnt++)
|
||||
{
|
||||
int const listsectnum = 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 endwall = sec->wallptr + sec->wallnum;
|
||||
auto uwal = (uwallptr_t)&wall[startwall];
|
||||
|
||||
for (int j=startwall; j<endwall; j++, uwal++)
|
||||
if (uwal->nextsector >= 0 && getsectordist({x, y}, uwal->nextsector) <= maxDistance)
|
||||
bfirst_search_try(sectlist, sectbitmap, &nsecs, uwal->nextsector);
|
||||
}
|
||||
}
|
||||
|
||||
*sectnum = -1;
|
||||
}
|
||||
|
||||
void updatesectorneighbourz(int32_t const x, int32_t const y, int32_t const z, int16_t * const sectnum, int32_t initialMaxDistance /*= 0*/, int32_t maxDistance /*= 0*/)
|
||||
{
|
||||
bool nofirstzcheck = false;
|
||||
|
||||
|
@ -11498,7 +11520,7 @@ void updatesectorz(int32_t const x, int32_t const y, int32_t const z, int16_t *
|
|||
|
||||
uint32_t const correctedsectnum = (unsigned)*sectnum;
|
||||
|
||||
if (correctedsectnum < (unsigned)numsectors && getsectordist({x, y}, correctedsectnum) < INITIALUPDATESECTORDIST)
|
||||
if (correctedsectnum < (unsigned)numsectors && getsectordist({x, y}, correctedsectnum) <= initialMaxDistance)
|
||||
{
|
||||
int32_t cz, fz;
|
||||
getzsofslope(correctedsectnum, x, y, &cz, &fz);
|
||||
|
@ -11540,16 +11562,11 @@ void updatesectorz(int32_t const x, int32_t const y, int32_t const z, int16_t *
|
|||
auto uwal = (uwallptr_t)&wall[startwall];
|
||||
|
||||
for (int j=startwall; j<endwall; j++, uwal++)
|
||||
if (uwal->nextsector >= 0 && getsectordist({x, y}, uwal->nextsector) < MAXUPDATESECTORDIST)
|
||||
if (uwal->nextsector >= 0 && getsectordist({x, y}, uwal->nextsector) <= maxDistance)
|
||||
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_z_p(x, y, z, i))
|
||||
SET_AND_RETURN(*sectnum, i);
|
||||
|
||||
*sectnum = -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -546,6 +546,8 @@ static tokenmap_t const vm_keywords[] =
|
|||
{ "undefinevolume", CON_UNDEFINEVOLUME },
|
||||
{ "updatesector", CON_UPDATESECTOR },
|
||||
{ "updatesectorz", CON_UPDATESECTORZ },
|
||||
{ "updatesectorneighbour", CON_UPDATESECTORNEIGHBOUR },
|
||||
{ "updatesectorneighbourz", CON_UPDATESECTORNEIGHBOURZ },
|
||||
{ "useractor", CON_USERACTOR },
|
||||
{ "userquote", CON_USERQUOTE },
|
||||
{ "wackplayer", CON_WACKPLAYER },
|
||||
|
@ -4130,6 +4132,7 @@ setvarvar:
|
|||
case CON_GETFLORZOFSLOPE:
|
||||
case CON_GETCEILZOFSLOPE:
|
||||
case CON_UPDATESECTORZ:
|
||||
case CON_UPDATESECTORNEIGHBOURZ:
|
||||
C_GetManyVars(3);
|
||||
C_GetNextVarType(GAMEVAR_READONLY);
|
||||
continue;
|
||||
|
@ -4548,6 +4551,7 @@ ifvar:
|
|||
|
||||
case CON_CANSEESPR:
|
||||
case CON_UPDATESECTOR:
|
||||
case CON_UPDATESECTORNEIGHBOUR:
|
||||
case CON_QSTRCMP:
|
||||
C_GetManyVars(2);
|
||||
C_GetNextVarType(GAMEVAR_READONLY);
|
||||
|
|
|
@ -1321,6 +1321,8 @@ enum IterationTypes_t
|
|||
TRANSFORM(CON_TOSSWEAPON) DELIMITER \
|
||||
TRANSFORM(CON_UPDATESECTOR) DELIMITER \
|
||||
TRANSFORM(CON_UPDATESECTORZ) DELIMITER \
|
||||
TRANSFORM(CON_UPDATESECTORNEIGHBOUR) DELIMITER \
|
||||
TRANSFORM(CON_UPDATESECTORNEIGHBOURZ) DELIMITER \
|
||||
TRANSFORM(CON_USERQUOTE) DELIMITER \
|
||||
TRANSFORM(CON_WACKPLAYER) DELIMITER \
|
||||
TRANSFORM(CON_WRITEARRAYTOFILE) DELIMITER \
|
||||
|
|
|
@ -4740,6 +4740,40 @@ badindex:
|
|||
dispatch();
|
||||
}
|
||||
|
||||
vInstruction(CON_UPDATESECTORNEIGHBOUR):
|
||||
insptr++;
|
||||
{
|
||||
vec2_t vect = { 0, 0 };
|
||||
Gv_FillWithVars(vect);
|
||||
|
||||
int const returnVar = *insptr++;
|
||||
int16_t sectNum = Gv_GetVar(returnVar);
|
||||
|
||||
if ((unsigned)sectNum >= MAXSECTORS)
|
||||
sectNum = vm.pSprite->sectnum;
|
||||
|
||||
updatesectorneighbour(vect.x, vect.y, §Num, getsectordist(vect, sectNum));
|
||||
Gv_SetVar(returnVar, sectNum);
|
||||
dispatch();
|
||||
}
|
||||
|
||||
vInstruction(CON_UPDATESECTORNEIGHBOURZ):
|
||||
insptr++;
|
||||
{
|
||||
vec3_t vect = { 0, 0, 0 };
|
||||
Gv_FillWithVars(vect);
|
||||
|
||||
int const returnVar = *insptr++;
|
||||
int16_t sectNum = Gv_GetVar(returnVar);
|
||||
|
||||
if ((unsigned)sectNum >= MAXSECTORS)
|
||||
sectNum = vm.pSprite->sectnum;
|
||||
|
||||
updatesectorneighbourz(vect.x, vect.y, vect.z, §Num, getsectordist({vect.x, vect.y}, sectNum));
|
||||
Gv_SetVar(returnVar, sectNum);
|
||||
dispatch();
|
||||
}
|
||||
|
||||
vInstruction(CON_SPAWN):
|
||||
insptr++;
|
||||
|
||||
|
|
|
@ -341,6 +341,8 @@ const char *keyw[] =
|
|||
"updatecursectnum",
|
||||
"updatesector",
|
||||
"updatesectorz",
|
||||
"updatesectorneighbour",
|
||||
"updatesectorneighbourz",
|
||||
"getzrange",
|
||||
"clipmove",
|
||||
"lineintersect",
|
||||
|
@ -3063,8 +3065,10 @@ repeatcase:
|
|||
|
||||
case CON_UPDATESECTOR:
|
||||
case CON_UPDATESECTORZ:
|
||||
case CON_UPDATESECTORNEIGHBOUR:
|
||||
case CON_UPDATESECTORNEIGHBOURZ:
|
||||
C_GetManyVars(2);
|
||||
if (tw==CON_UPDATESECTORZ)
|
||||
if (tw==CON_UPDATESECTORZ || tw==CON_UPDATESECTORNEIGHBOURZ)
|
||||
C_GetNextVar();
|
||||
C_GetNextVarType(GV_WRITABLE);
|
||||
break;
|
||||
|
|
|
@ -475,6 +475,8 @@ enum ScriptKeywords_t
|
|||
CON_UPDATECURSECTNUM,
|
||||
CON_UPDATESECTOR,
|
||||
CON_UPDATESECTORZ,
|
||||
CON_UPDATESECTORNEIGHBOUR,
|
||||
CON_UPDATESECTORNEIGHBOURZ,
|
||||
CON_GETZRANGE,
|
||||
CON_CLIPMOVE,
|
||||
CON_LINEINTERSECT,
|
||||
|
|
|
@ -2116,18 +2116,33 @@ badindex:
|
|||
|
||||
case CON_UPDATESECTOR:
|
||||
case CON_UPDATESECTORZ:
|
||||
case CON_UPDATESECTORNEIGHBOUR:
|
||||
case CON_UPDATESECTORNEIGHBOURZ:
|
||||
insptr++;
|
||||
{
|
||||
int32_t x=Gv_GetVar(*insptr++), y=Gv_GetVar(*insptr++);
|
||||
int32_t z=(tw==CON_UPDATESECTORZ)?Gv_GetVar(*insptr++):0;
|
||||
int32_t z=(tw==CON_UPDATESECTORZ || tw==CON_UPDATESECTORNEIGHBOURZ)?Gv_GetVar(*insptr++):0;
|
||||
int32_t var=*insptr++;
|
||||
int16_t w;
|
||||
|
||||
X_ERROR_INVALIDCI();
|
||||
w=sprite[vm.spriteNum].sectnum;
|
||||
|
||||
if (tw==CON_UPDATESECTOR) updatesector(x,y,&w);
|
||||
else updatesectorz(x,y,z,&w);
|
||||
switch (tw)
|
||||
{
|
||||
case CON_UPDATESECTORNEIGHBOURZ:
|
||||
updatesectorneighbourz(x,y,z,&w,getsectordist({x, y}, w));
|
||||
continue;
|
||||
case CON_UPDATESECTORZ:
|
||||
updatesectorz(x,y,z,&w);
|
||||
continue;
|
||||
case CON_UPDATESECTORNEIGHBOUR:
|
||||
updatesectorneighbour(x,y,&w,getsectordist({x, y}, w));
|
||||
continue;
|
||||
default:
|
||||
updatesector(x,y,&w);
|
||||
continue;
|
||||
}
|
||||
|
||||
Gv_SetVar(var, w);
|
||||
continue;
|
||||
|
|
Loading…
Reference in a new issue