engine: consider a point inside() a sector in all border cases (literally).

In other words, for a test rectangular sector, a sprite would be inside the
sector in on all 4 edges and all 4 corners. Previously, it would have been
the lower right portion only (*excluding* LL and UR corners), which led to
map editing issues.

git-svn-id: https://svn.eduke32.com/eduke32@3898 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2013-06-22 11:31:16 +00:00
parent 8b4a87925b
commit db7f820404
2 changed files with 34 additions and 12 deletions

View file

@ -11383,20 +11383,26 @@ int32_t clipinsideboxline(int32_t x, int32_t y, int32_t x1, int32_t y1, int32_t
// //
// inside // 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) int32_t inside(int32_t x, int32_t y, int16_t sectnum)
{ {
if (sectnum >= 0 && sectnum < numsectors) if (sectnum >= 0 && sectnum < numsectors)
{ {
uint32_t cnt = 0; uint32_t cnt1 = 0, cnt2 = 0;
walltype *wal = &wall[sector[sectnum].wallptr]; walltype *wal = &wall[sector[sectnum].wallptr];
int32_t i = sector[sectnum].wallnum; int32_t i = sector[sectnum].wallnum;
do do
{ {
// Get the y components of the [tested point]-->[wall point{1,2}] // Get the x and y components of the [tested point]-->[wall
// vectors. // point{1,2}] vectors.
const int32_t y1 = wal->y - y; int32_t x1 = wal->x-x, x2 = wall[wal->point2].x-x;
const int32_t y2 = wall[wal->point2].y - y; int32_t y1 = wal->y-y, y2 = wall[wal->point2].y-y;
// First, test if the point is EXACTLY_ON_WALL_POINT.
if ((x1|y1) == 0 || (x2|y2)==0)
return 1;
// If their signs differ[*], ... // If their signs differ[*], ...
// //
@ -11406,21 +11412,37 @@ int32_t inside(int32_t x, int32_t y, int16_t sectnum)
// where y_m := min(y1, y2) and y_M := max(y1, y2). // where y_m := min(y1, y2) and y_M := max(y1, y2).
if ((y1^y2) < 0) if ((y1^y2) < 0)
{ {
// ... get the x components. if ((x1^x2) >= 0)
const int32_t x1 = wal->x - x; cnt1 ^= x1;
const int32_t x2 = wall[wal->point2].x - x; else
cnt1 ^= (x1*y2-x2*y1)^y2;
}
y1--;
y2--;
// Now, do the same comparisons, but with the interval half-open on
// the other side! That is, take the branch iff
// y1 != y2 AND y_m < wal->y <= y_M,
// For a rectangular sector, without EXACTLY_ON_WALL_POINT, this
// would still leave the lower left and upper right points
// "outside" the sector.
if ((y1^y2) < 0)
{
x1--;
x2--;
if ((x1^x2) >= 0) if ((x1^x2) >= 0)
cnt ^= x1; cnt2 ^= x1;
else else
cnt ^= (x1*y2-x2*y1)^y2; cnt2 ^= (x1*y2-x2*y1)^y2;
} }
wal++; i--; wal++; i--;
} }
while (i); while (i);
return cnt>>31; return (cnt1|cnt2)>>31;
} }
return -1; return -1;

View file

@ -506,7 +506,7 @@ local sectortype_mt = {
{ florhit>=49152, bit.band(florhit,16383), florz }) { florhit>=49152, bit.band(florhit,16383), florz })
end, end,
-- inside() port -- inside() port, OUTOFSYNC with engine.c
contains = function(s, pos) contains = function(s, pos)
local x, y = pos.x, pos.y local x, y = pos.x, pos.y
local cnt = 0 local cnt = 0