mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-25 03:00:46 +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 (*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 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);
|
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);
|
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 dragpoint(int16_t pointhighlight, int32_t dax, int32_t day, uint8_t flags);
|
||||||
void setfirstwall(int16_t sectnum, int16_t newfirstwall);
|
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,
|
int32_t vx, int32_t vy, int32_t vz,
|
||||||
vec3_t *intp, int32_t strictly_smaller_than_p);
|
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);
|
int findwallbetweensectors(int sect1, int sect2);
|
||||||
static FORCE_INLINE bool sectoradjacent(int sect1, int sect2) { return findwallbetweensectors(sect1, sect2) != -1; }
|
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);
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#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)
|
||||||
{
|
{
|
||||||
int const initialsectnum = *sectnum;
|
int16_t sect = *sectnum;
|
||||||
|
updatesectorneighbour(x, y, §, INITIALUPDATESECTORDIST, MAXUPDATESECTORDIST);
|
||||||
if ((unsigned)initialsectnum < (unsigned)numsectors && getsectordist({x, y}, initialsectnum) < INITIALUPDATESECTORDIST)
|
if (sect != -1)
|
||||||
{
|
SET_AND_RETURN(*sectnum, sect);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// we need to support passing in a sectnum of -1, unfortunately
|
// 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)
|
// (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)
|
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;
|
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;
|
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;
|
int32_t cz, fz;
|
||||||
getzsofslope(correctedsectnum, x, y, &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];
|
auto uwal = (uwallptr_t)&wall[startwall];
|
||||||
|
|
||||||
for (int j=startwall; j<endwall; j++, uwal++)
|
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);
|
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;
|
*sectnum = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -546,6 +546,8 @@ static tokenmap_t const vm_keywords[] =
|
||||||
{ "undefinevolume", CON_UNDEFINEVOLUME },
|
{ "undefinevolume", CON_UNDEFINEVOLUME },
|
||||||
{ "updatesector", CON_UPDATESECTOR },
|
{ "updatesector", CON_UPDATESECTOR },
|
||||||
{ "updatesectorz", CON_UPDATESECTORZ },
|
{ "updatesectorz", CON_UPDATESECTORZ },
|
||||||
|
{ "updatesectorneighbour", CON_UPDATESECTORNEIGHBOUR },
|
||||||
|
{ "updatesectorneighbourz", CON_UPDATESECTORNEIGHBOURZ },
|
||||||
{ "useractor", CON_USERACTOR },
|
{ "useractor", CON_USERACTOR },
|
||||||
{ "userquote", CON_USERQUOTE },
|
{ "userquote", CON_USERQUOTE },
|
||||||
{ "wackplayer", CON_WACKPLAYER },
|
{ "wackplayer", CON_WACKPLAYER },
|
||||||
|
@ -4130,6 +4132,7 @@ setvarvar:
|
||||||
case CON_GETFLORZOFSLOPE:
|
case CON_GETFLORZOFSLOPE:
|
||||||
case CON_GETCEILZOFSLOPE:
|
case CON_GETCEILZOFSLOPE:
|
||||||
case CON_UPDATESECTORZ:
|
case CON_UPDATESECTORZ:
|
||||||
|
case CON_UPDATESECTORNEIGHBOURZ:
|
||||||
C_GetManyVars(3);
|
C_GetManyVars(3);
|
||||||
C_GetNextVarType(GAMEVAR_READONLY);
|
C_GetNextVarType(GAMEVAR_READONLY);
|
||||||
continue;
|
continue;
|
||||||
|
@ -4548,6 +4551,7 @@ ifvar:
|
||||||
|
|
||||||
case CON_CANSEESPR:
|
case CON_CANSEESPR:
|
||||||
case CON_UPDATESECTOR:
|
case CON_UPDATESECTOR:
|
||||||
|
case CON_UPDATESECTORNEIGHBOUR:
|
||||||
case CON_QSTRCMP:
|
case CON_QSTRCMP:
|
||||||
C_GetManyVars(2);
|
C_GetManyVars(2);
|
||||||
C_GetNextVarType(GAMEVAR_READONLY);
|
C_GetNextVarType(GAMEVAR_READONLY);
|
||||||
|
|
|
@ -1321,6 +1321,8 @@ enum IterationTypes_t
|
||||||
TRANSFORM(CON_TOSSWEAPON) DELIMITER \
|
TRANSFORM(CON_TOSSWEAPON) DELIMITER \
|
||||||
TRANSFORM(CON_UPDATESECTOR) DELIMITER \
|
TRANSFORM(CON_UPDATESECTOR) DELIMITER \
|
||||||
TRANSFORM(CON_UPDATESECTORZ) DELIMITER \
|
TRANSFORM(CON_UPDATESECTORZ) DELIMITER \
|
||||||
|
TRANSFORM(CON_UPDATESECTORNEIGHBOUR) DELIMITER \
|
||||||
|
TRANSFORM(CON_UPDATESECTORNEIGHBOURZ) DELIMITER \
|
||||||
TRANSFORM(CON_USERQUOTE) DELIMITER \
|
TRANSFORM(CON_USERQUOTE) DELIMITER \
|
||||||
TRANSFORM(CON_WACKPLAYER) DELIMITER \
|
TRANSFORM(CON_WACKPLAYER) DELIMITER \
|
||||||
TRANSFORM(CON_WRITEARRAYTOFILE) DELIMITER \
|
TRANSFORM(CON_WRITEARRAYTOFILE) DELIMITER \
|
||||||
|
|
|
@ -4740,6 +4740,40 @@ badindex:
|
||||||
dispatch();
|
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):
|
vInstruction(CON_SPAWN):
|
||||||
insptr++;
|
insptr++;
|
||||||
|
|
||||||
|
|
|
@ -341,6 +341,8 @@ const char *keyw[] =
|
||||||
"updatecursectnum",
|
"updatecursectnum",
|
||||||
"updatesector",
|
"updatesector",
|
||||||
"updatesectorz",
|
"updatesectorz",
|
||||||
|
"updatesectorneighbour",
|
||||||
|
"updatesectorneighbourz",
|
||||||
"getzrange",
|
"getzrange",
|
||||||
"clipmove",
|
"clipmove",
|
||||||
"lineintersect",
|
"lineintersect",
|
||||||
|
@ -3063,8 +3065,10 @@ repeatcase:
|
||||||
|
|
||||||
case CON_UPDATESECTOR:
|
case CON_UPDATESECTOR:
|
||||||
case CON_UPDATESECTORZ:
|
case CON_UPDATESECTORZ:
|
||||||
|
case CON_UPDATESECTORNEIGHBOUR:
|
||||||
|
case CON_UPDATESECTORNEIGHBOURZ:
|
||||||
C_GetManyVars(2);
|
C_GetManyVars(2);
|
||||||
if (tw==CON_UPDATESECTORZ)
|
if (tw==CON_UPDATESECTORZ || tw==CON_UPDATESECTORNEIGHBOURZ)
|
||||||
C_GetNextVar();
|
C_GetNextVar();
|
||||||
C_GetNextVarType(GV_WRITABLE);
|
C_GetNextVarType(GV_WRITABLE);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -475,6 +475,8 @@ enum ScriptKeywords_t
|
||||||
CON_UPDATECURSECTNUM,
|
CON_UPDATECURSECTNUM,
|
||||||
CON_UPDATESECTOR,
|
CON_UPDATESECTOR,
|
||||||
CON_UPDATESECTORZ,
|
CON_UPDATESECTORZ,
|
||||||
|
CON_UPDATESECTORNEIGHBOUR,
|
||||||
|
CON_UPDATESECTORNEIGHBOURZ,
|
||||||
CON_GETZRANGE,
|
CON_GETZRANGE,
|
||||||
CON_CLIPMOVE,
|
CON_CLIPMOVE,
|
||||||
CON_LINEINTERSECT,
|
CON_LINEINTERSECT,
|
||||||
|
|
|
@ -2116,18 +2116,33 @@ badindex:
|
||||||
|
|
||||||
case CON_UPDATESECTOR:
|
case CON_UPDATESECTOR:
|
||||||
case CON_UPDATESECTORZ:
|
case CON_UPDATESECTORZ:
|
||||||
|
case CON_UPDATESECTORNEIGHBOUR:
|
||||||
|
case CON_UPDATESECTORNEIGHBOURZ:
|
||||||
insptr++;
|
insptr++;
|
||||||
{
|
{
|
||||||
int32_t x=Gv_GetVar(*insptr++), y=Gv_GetVar(*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++;
|
int32_t var=*insptr++;
|
||||||
int16_t w;
|
int16_t w;
|
||||||
|
|
||||||
X_ERROR_INVALIDCI();
|
X_ERROR_INVALIDCI();
|
||||||
w=sprite[vm.spriteNum].sectnum;
|
w=sprite[vm.spriteNum].sectnum;
|
||||||
|
|
||||||
if (tw==CON_UPDATESECTOR) updatesector(x,y,&w);
|
switch (tw)
|
||||||
else updatesectorz(x,y,z,&w);
|
{
|
||||||
|
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);
|
Gv_SetVar(var, w);
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Reference in a new issue