mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-15 08:51:24 +00:00
- redid the 'inside' function.
This is based on external information and does not use any of the original Build code. Despite being a lot clearer than Build's bit masking voodoo and using 64 bit math to avoid overflows it is roughly 10% faster. :) Code was moved to gamefuncs.cpp because this no longer falls under the Build license.
This commit is contained in:
parent
5cfc418c5f
commit
c034c2a299
2 changed files with 42 additions and 40 deletions
|
@ -697,46 +697,6 @@ void initspritelists(void)
|
|||
Numsprites = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// inside
|
||||
//
|
||||
// See http://fabiensanglard.net/duke3d/build_engine_internals.php,
|
||||
// "Inside details" for the idea behind the algorithm.
|
||||
|
||||
int32_t inside(int32_t x, int32_t y, int16_t sectnum)
|
||||
{
|
||||
if (validSectorIndex(sectnum))
|
||||
{
|
||||
uint32_t cnt = 0;
|
||||
auto wal = (uwallptr_t)&wall[sector[sectnum].wallptr];
|
||||
int wallsleft = sector[sectnum].wallnum;
|
||||
|
||||
do
|
||||
{
|
||||
// Get the x and y components of the [tested point]-->[wall
|
||||
// point{1,2}] vectors.
|
||||
vec2_t v1 = { wal->x - x, wal->y - y };
|
||||
auto const &wal2 = *(uwallptr_t)&wall[wal->point2];
|
||||
vec2_t v2 = { wal2.x - x, wal2.y - y };
|
||||
|
||||
// If their signs differ[*], ...
|
||||
//
|
||||
// [*] where '-' corresponds to <0 and '+' corresponds to >=0.
|
||||
// Equivalently, the branch is taken iff
|
||||
// y1 != y2 AND y_m <= y < y_M,
|
||||
// where y_m := min(y1, y2) and y_M := max(y1, y2).
|
||||
if ((v1.y^v2.y) < 0)
|
||||
cnt ^= (((v1.x^v2.x) >= 0) ? v1.x : (v1.x*v2.y-v2.x*v1.y)^v2.y);
|
||||
|
||||
wal++;
|
||||
}
|
||||
while (--wallsleft);
|
||||
|
||||
return cnt>>31;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int32_t getangle(int32_t xvect, int32_t yvect)
|
||||
|
|
|
@ -148,6 +148,48 @@ bool calcChaseCamPos(int* px, int* py, int* pz, spritetype* pspr, int *psectnum,
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// checks if a point is within a given sector
|
||||
//
|
||||
// Completely redone based on outside information.
|
||||
// The math in here is based on this article: https://wrf.ecse.rpi.edu/Research/Short_Notes/pnpoly.html
|
||||
// Copyright (c) 1970-2003, Wm. Randolph Franklin , licensed under BSD 3-clause
|
||||
// but was transformed to avoid the division it contained and to properly pick the vertices of Build walls.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int inside(int x, int y, int sectnum)
|
||||
{
|
||||
if (validSectorIndex(sectnum))
|
||||
{
|
||||
bool c = false;
|
||||
for (auto& wal : wallsofsector(sectnum))
|
||||
{
|
||||
auto& pt1 = wal.pos;
|
||||
auto& pt2 = wal.point2Wall()->pos;
|
||||
|
||||
if ((pt1.y > y) != (pt2.y > y)) // skip if both are on the same side.
|
||||
{
|
||||
// use 64 bit values to avoid overflows in the multiplications below.
|
||||
int64_t deltatx = int64_t(x) - pt1.x;
|
||||
int64_t deltaty = int64_t(y) - pt1.y;
|
||||
int64_t deltax = int64_t(pt2.x) - pt1.x;
|
||||
int64_t deltay = int64_t(pt2.y) - pt1.y;
|
||||
// reformatted to avoid the division - for negative deltay the sign needs to be flipped to give the correct result.
|
||||
//if (x < deltax * (deltaty) / deltay + pt1.x) // this was the original code.
|
||||
if (((deltay * deltatx - deltax * deltaty) ^ deltay) < 0)
|
||||
{
|
||||
c = !c;
|
||||
}
|
||||
}
|
||||
}
|
||||
return int(c);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// note that this returns values in renderer coordinate space with inverted sign!
|
||||
|
|
Loading…
Reference in a new issue