- updatesector* cleanup.

got rid of all remaining Build code in here, stripped down the wrapper interface and moved everything into a separate header file.
This commit is contained in:
Christoph Oelckers 2022-08-04 23:48:07 +02:00
parent e1eb54ecda
commit dcb4e1e39b
5 changed files with 137 additions and 131 deletions

View file

@ -149,28 +149,6 @@ int32_t try_facespr_intersect(DCoreActor* spr, vec3_t const in,
int32_t vx, int32_t vy, int32_t vz,
vec3_t * const intp, int32_t strictly_smaller_than_p);
#define MAXUPDATESECTORDIST 1536
#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)
{
int sectno = *sectp? sector.IndexOf(*sectp) : -1;
updatesector(x, y, &sectno);
*sectp = sectno == -1? nullptr : &sector[sectno];
}
void updatesectorz(int32_t const x, int32_t const y, int32_t const z, int * const sectnum) ATTRIBUTE((nonnull(4)));
inline void updatesectorz(int32_t const x, int32_t const y, int32_t const z, sectortype** const sectp)
{
int sectno = *sectp ? sector.IndexOf(*sectp) : -1;
updatesectorz(x, y, z, &sectno);
*sectp = sectno == -1 ? nullptr : &sector[sectno];
}
void updatesectorneighbor(int32_t const x, int32_t const y, int * const sectnum, int32_t maxDistance = MAXUPDATESECTORDIST) ATTRIBUTE((nonnull(3)));
extern const int16_t *chsecptr_onextwall;

View file

@ -449,106 +449,6 @@ void neartag(const vec3_t& sv, sectortype* sect, int ange, HitInfoBase& result,
}
////////// UPDATESECTOR* FAMILY OF FUNCTIONS //////////
/* Different "is inside" predicates.
* NOTE: The redundant bound checks are expected to be optimized away in the
* inlined code. */
/* NOTE: no bound check */
static inline int inside_z_p(int32_t const x, int32_t const y, int32_t const z, int const sectnum)
{
int32_t cz, fz;
getzsofslopeptr(&sector[sectnum], x, y, &cz, &fz);
return (z >= cz && z <= fz && inside_p(x, y, sectnum));
}
int32_t getwalldist(vec2_t const in, int const wallnum, vec2_t * const out)
{
auto dvec = NearestPointOnWall(in.X * maptoworld, in.Y * maptoworld, &wall[wallnum]);
*out = { int(dvec.X * worldtoint), int(dvec.Y * worldtoint) };
return abs(out->X - in.X) + abs(out->Y - in.Y);
}
template<class Inside>
void updatesectorneighborz(int32_t const x, int32_t const y, int32_t const z, int* const sectnum, int32_t maxDistance, Inside checker)
{
int const initialsectnum = *sectnum;
double maxDist = maxDistance * inttoworld; maxDist *= maxDist;
if ((validSectorIndex(initialsectnum)))
{
if (checker(x, y, z, initialsectnum))
return;
BFSSearch search(sector.Size(), *sectnum);
int iter = 0;
for (unsigned listsectnum; (listsectnum = search.GetNext()) != BFSSearch::EOL;)
{
if (checker(x, y, z, listsectnum))
{
*sectnum = listsectnum;
return;
}
for (auto& wal : wallsofsector(listsectnum))
{
if (wal.nextsector >= 0 && (iter == 0 || SquareDistToSector(x * inttoworld, y * inttoworld, wal.nextSector()) <= maxDist))
search.Add(wal.nextsector);
}
iter++;
}
}
*sectnum = -1;
}
void updatesectorneighbor(int32_t const x, int32_t const y, int* const sectnum, int32_t maxDistance)
{
updatesectorneighborz(x, y, 0, sectnum, maxDistance, inside_p0);
}
//
// updatesector[z]
//
void updatesector(int32_t const x, int32_t const y, int * const sectnum)
{
int sect = *sectnum;
updatesectorneighbor(x, y, &sect, MAXUPDATESECTORDIST);
if (sect != -1)
SET_AND_RETURN(*sectnum, sect);
// we need to support passing in a sectnum of -1, unfortunately
for (int i = (int)sector.Size() - 1; i >= 0; --i)
if (inside_p(x, y, i))
SET_AND_RETURN(*sectnum, i);
*sectnum = -1;
}
void updatesectorz(int32_t const x, int32_t const y, int32_t const z, int* const sectnum)
{
int sect = *sectnum;
updatesectorneighborz(x, y, z, &sect, MAXUPDATESECTORDIST, inside_z_p);
if (sect != -1)
SET_AND_RETURN(*sectnum, sect);
// we need to support passing in a sectnum of -1, unfortunately
for (int i = (int)sector.Size() - 1; i >= 0; --i)
if (inside_z_p(x, y, z, i))
SET_AND_RETURN(*sectnum, i);
*sectnum = -1;
}
//
// rotatepoint

View file

@ -181,7 +181,7 @@ void calcSlope(const sectortype* sec, float xpos, float ypos, float* pceilz, flo
//==========================================================================
//
// for the renderer (Polymost variants are in polymost.cpp)
// for the renderer
//
//==========================================================================
@ -220,6 +220,14 @@ void getzsofslopeptr(const sectortype* sec, int dax, int day, int* ceilz, int* f
*florz = int(f);
}
void getzsofslopeptr(const sectortype* sec, double dax, double day, double* ceilz, double* florz)
{
float c, f;
calcSlope(sec, dax * worldtoint, day * worldtoint, &c, &f);
*ceilz = c * zinttoworld;
*florz = f * zinttoworld;
}
void getcorrectzsofslope(int sectnum, int dax, int day, int* ceilz, int* florz)
{
DVector2 closestv;

View file

@ -178,6 +178,7 @@ void getcorrectzsofslope(int sectnum, int dax, int day, int* ceilz, int* florz);
int getceilzofslopeptr(const sectortype* sec, int dax, int day);
int getflorzofslopeptr(const sectortype* sec, int dax, int day);
void getzsofslopeptr(const sectortype* sec, int dax, int day, int* ceilz, int* florz);
void getzsofslopeptr(const sectortype* sec, double dax, double day, double* ceilz, double* florz);
// y is negated so that the orientation is the same as in GZDoom, in order to use its utilities.
@ -316,8 +317,6 @@ inline int inside(int x, int y, const sectortype* sect)
// still needed by some parts in the engine.
inline int inside_p(int x, int y, int sectnum) { return (sectnum >= 0 && inside(x, y, &sector[sectnum]) == 1); }
// this one is for template substitution.
inline int inside_p0(int32_t const x, int32_t const y, int32_t const z, int const sectnum) { return inside_p(x, y, sectnum); }
@ -428,9 +427,5 @@ inline void alignflorslope(sectortype* sect, int x, int y, int z)
{
sect->setfloorslope(getslopeval(sect, x, y, z, sect->floorz));
}
inline void updatesectorneighbor(int32_t const x, int32_t const y, sectortype* * const sect, int32_t maxDistance = MAXUPDATESECTORDIST)
{
int sectno = *sect? sector.IndexOf(*sect) : -1;
updatesectorneighbor(x, y, &sectno, maxDistance);
*sect = sectno < 0? nullptr : &sector[sectno];
}
#include "updatesector.h"

125
source/core/updatesector.h Normal file
View file

@ -0,0 +1,125 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2022 Christoph Oelckers
This is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
//
// updatesector utilities. Uses a breadth-first algorithm similar
// but not identical to EDuke32's updatesectorneighbor.
// checker functions for updatesector's template parameter.
inline int inside0(double x, double y, double z, const sectortype* sect)
{
return inside(x, y, sect);
}
inline int insideZ(double x, double y, double z, const sectortype* sect)
{
double cz, fz;
getzsofslopeptr(sect, x, y, &cz, &fz);
return (z >= cz && z <= fz && inside(x, y, sect) != 0);
}
template<class Inside>
void DoUpdateSector(double x, double y, double z, int* sectnum, double maxDistance, Inside checker)
{
double maxDistSq = maxDistance * maxDistance;
if (sectnum)
{
if (checker(x, y, z, &sector[*sectnum]))
return;
BFSSearch search(sector.Size(), *sectnum);
int iter = 0;
for (unsigned listsectnum; (listsectnum = search.GetNext()) != BFSSearch::EOL;)
{
auto lsect = &sector[listsectnum];
if (checker(x, y, z, lsect))
{
*sectnum = listsectnum;
return;
}
for (auto& wal : wallsofsector(lsect))
{
if (wal.nextsector >= 0 && !search.Check(wal.nextsector) && (iter == 0 || SquareDistToSector(x, y, wal.nextSector()) <= maxDistSq))
search.Add(wal.nextsector);
}
iter++;
}
*sectnum = -1;
}
}
template<class Inside>
int FindSector(double x, double y, double z, Inside checker)
{
for (int i = (int)sector.Size() - 1; i >= 0; i--)
if (checker(x, y, z, &sector[i]))
{
return i;
}
return -1;
}
constexpr int MAXUPDATESECTORDIST = 1536;
inline void updatesector(int x_, int y_, int* sectnum)
{
double x = x_ * inttoworld;
double y = y_ * inttoworld;
DoUpdateSector(x, y, 0, sectnum, MAXUPDATESECTORDIST * inttoworld, inside0);
if (*sectnum == -1) *sectnum = FindSector(x, y, 0, inside0);
}
inline void updatesectorz(int x_, int y_, int z_, int* sectnum)
{
double x = x_ * inttoworld;
double y = y_ * inttoworld;
double z = z_ * zinttoworld;
DoUpdateSector(x, y, z, sectnum, MAXUPDATESECTORDIST * inttoworld, insideZ);
if (*sectnum == -1) *sectnum = FindSector(x, y, z, insideZ);
}
inline void updatesector(int const x, int const y, sectortype** const sectp)
{
int sectno = *sectp? sector.IndexOf(*sectp) : -1;
updatesector(x, y, &sectno);
*sectp = sectno == -1? nullptr : &sector[sectno];
}
inline void updatesectorz(int x, int y, int z, sectortype** const sectp)
{
int sectno = *sectp ? sector.IndexOf(*sectp) : -1;
updatesectorz(x, y, z, &sectno);
*sectp = sectno == -1 ? nullptr : &sector[sectno];
}
inline void updatesectorneighbor(int x, int y, sectortype** const sect, int maxDistance = MAXUPDATESECTORDIST)
{
int sectno = *sect? sector.IndexOf(*sect) : -1;
DoUpdateSector(x * inttoworld, y * inttoworld, 0, &sectno, maxDistance * inttoworld, inside0);
*sect = sectno < 0? nullptr : &sector[sectno];
}