mirror of
https://github.com/DrBeef/Raze.git
synced 2025-01-20 08:00:56 +00:00
- use engine utilities for the section builder’s inside check
This commit is contained in:
parent
f5e6503b26
commit
b2d1988e50
2 changed files with 43 additions and 69 deletions
|
@ -492,6 +492,33 @@ void dragpoint(walltype* startwall, const DVector2& pos)
|
|||
});
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int64_t checkforinside(double x, double y, const DVector2& pt1, const DVector2& pt2)
|
||||
{
|
||||
// Perform the checks here in 48.16 fixed point.
|
||||
// Doing it directly with floats and multiplications does not work reliably due to underflows.
|
||||
// Unfortunately, due to the conversions, this is a bit slower. :(
|
||||
int64_t xs = int64_t(0x10000 * (pt1.X - x));
|
||||
int64_t ys = int64_t(0x10000 * (pt1.Y - y));
|
||||
int64_t xe = int64_t(0x10000 * (pt2.X - x));
|
||||
int64_t ye = int64_t(0x10000 * (pt2.Y - y));
|
||||
|
||||
if ((ys ^ ye) < 0)
|
||||
{
|
||||
int64_t val;
|
||||
|
||||
if ((xs ^ xe) >= 0) val = xs;
|
||||
else val = ((xs * ye) - xe * ys) ^ ye;
|
||||
return val;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -505,23 +532,7 @@ int inside(double x, double y, const sectortype* sect)
|
|||
int64_t acc = 1;
|
||||
for (auto& wal : wallsofsector(sect))
|
||||
{
|
||||
// Perform the checks here in 48.16 fixed point.
|
||||
// Doing it directly with floats and multiplications does not work reliably.
|
||||
// Unfortunately, due to the conversions, this is a bit slower. :(
|
||||
int64_t xs = int64_t(0x10000 * (wal.pos.X - x));
|
||||
int64_t ys = int64_t(0x10000 * (wal.pos.Y - y));
|
||||
auto wal2 = wal.point2Wall();
|
||||
int64_t xe = int64_t(0x10000 * (wal2->pos.X - x));
|
||||
int64_t ye = int64_t(0x10000 * (wal2->pos.Y - y));
|
||||
|
||||
if ((ys ^ ye) < 0)
|
||||
{
|
||||
int64_t val;
|
||||
|
||||
if ((xs ^ xe) >= 0) val = xs;
|
||||
else val = ((xs * ye) - xe * ys) ^ ye;
|
||||
acc ^= val;
|
||||
}
|
||||
acc ^= checkforinside(x, y, wal.pos, wal.point2Wall()->pos);
|
||||
}
|
||||
return acc < 0;
|
||||
}
|
||||
|
@ -540,25 +551,9 @@ int insidePoly(double x, double y, const DVector2* points, int count)
|
|||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
int j = (i + 1) % count;
|
||||
// Perform the checks here in 48.16 fixed point.
|
||||
// Doing it directly with floats and multiplications does not work reliably.
|
||||
// Unfortunately, due to the conversions, this is a bit slower. :(
|
||||
int64_t xs = int64_t(0x10000 * (points[i].X - x));
|
||||
int64_t ys = int64_t(0x10000 * (points[i].Y - y));
|
||||
int64_t xe = int64_t(0x10000 * (points[j].X - x));
|
||||
int64_t ye = int64_t(0x10000 * (points[j].Y - y));
|
||||
|
||||
if ((ys ^ ye) < 0)
|
||||
{
|
||||
int64_t val;
|
||||
|
||||
if ((xs ^ xe) >= 0) val = xs;
|
||||
else val = ((xs * ye) - xe * ys) ^ ye;
|
||||
acc ^= val;
|
||||
}
|
||||
acc ^= checkforinside(x, y, points[i], points[j]);
|
||||
}
|
||||
return acc < 0;
|
||||
|
||||
return acc < 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -288,45 +288,24 @@ static void CollectLoops(TArray<loopcollect>& sectors)
|
|||
//
|
||||
// checks if a point is within a given section
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// (not used in-game because it is not 100% identical to Build's original check and causing issues in SW.)
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static TArray<DVector2> points;
|
||||
static int insideLoop(int vertex, TArray<int>& loop)
|
||||
{
|
||||
auto pt = wall[vertex].wall_int_pos();
|
||||
points.Resize(loop.Size() - 1);
|
||||
for (unsigned ii = 0; ii < loop.Size() - 1; ii++)
|
||||
{
|
||||
points[ii] = wall[loop[ii]].pos;
|
||||
}
|
||||
|
||||
// to reliably detect walls where vertices lie directly on outer walls, we must test the wall's center as well.
|
||||
// SW: Wanton Destrcution's $bath.map, sector 601 is an example for that.
|
||||
DVector2 pts[] = { wall[vertex].pos, wall[vertex].center() };
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
// to reliably detect walls where vertices lie directly on outer walls, we must test the wall's center as well.
|
||||
// SW: Wanton Destrcution's $bath.map, sector 601 is an example for that.
|
||||
if (i == 1) pt += wall[vertex].int_delta() / 2;
|
||||
bool c = false;
|
||||
for (unsigned ii = 0; ii < loop.Size() - 1; ii++)
|
||||
{
|
||||
auto& wal = wall[loop[ii]];
|
||||
const auto pt1 = wal.wall_int_pos();
|
||||
const auto pt2 = wal.point2Wall()->wall_int_pos();
|
||||
|
||||
if ((pt1.Y >pt.Y) != (pt2.Y > pt.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(pt.X) - pt1.X;
|
||||
int64_t deltaty = int64_t(pt.Y) - pt1.Y;
|
||||
int64_t deltax = int64_t(pt2.X) - pt1.X;
|
||||
int64_t deltay = int64_t(pt2.Y) - pt1.Y;
|
||||
//if (x < deltax * (deltaty) / deltay + pt1.x)
|
||||
// reformatted to avoid the division - for nagative deltay the sign needs to be flipped to give the correct result.
|
||||
int64_t result = ((deltay * deltatx - deltax * deltaty) ^ deltay);
|
||||
if (result < 0)
|
||||
c = !c;
|
||||
}
|
||||
}
|
||||
if (i == 1 || c == 1) return int(c);
|
||||
int isinside = insidePoly(pts[i].X, pts[i].Y, points.Data(), points.Size());
|
||||
if (isinside == 1) return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -504,7 +483,7 @@ static void GroupData(TArray<loopcollect>& collect, TArray<sectionbuildsector>&
|
|||
if (!tossit) // Have we created our dumping section yet? If no, do so now and print a warning.
|
||||
{
|
||||
tossit = true;
|
||||
Printf("Potential problem at sector %d with %d loops\n", i, sectloops.Size());
|
||||
//Printf("Potential problem at sector %d with %d loops\n", i, sectloops.Size());
|
||||
bugged.Insert(i, true);
|
||||
builder.sections.Reserve(1);
|
||||
builder.sections.Last().bugged = ESectionFlag::Dumped; // this will most likely require use of the node builder to triangulate anyway.
|
||||
|
|
Loading…
Reference in a new issue