- cansee floating point rewrite using backend utilities.

This commit is contained in:
Christoph Oelckers 2022-09-24 20:30:00 +02:00
parent 14a8dd451e
commit 28a169d02d
4 changed files with 54 additions and 74 deletions

View file

@ -185,13 +185,6 @@ inline void neartag(const DVector3& start, sectortype* sect, DAngle angle, HitIn
neartag(vec, sect, angle.Buildang(), result, int(neartagrange * worldtoint), tagsearch);
}
int cansee(int x1, int y1, int z1, sectortype* sect1, int x2, int y2, int z2, sectortype* sect2);
inline int cansee(const DVector3& start, sectortype* sect1, const DVector3& end, sectortype* sect2)
{
return cansee(start.X * worldtoint, start.Y * worldtoint, start.Z * zworldtoint, sect1, end.X * worldtoint, end.Y * worldtoint, end.Z * zworldtoint, sect2);
}
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);

View file

@ -59,71 +59,6 @@ void engineInit(void)
}
//
// cansee
//
int cansee(int x1, int y1, int z1, sectortype* sect1, int x2, int y2, int z2, sectortype* sect2)
{
if (!sect1 || !sect2) return false;
const int32_t x21 = x2-x1, y21 = y2-y1, z21 = z2-z1;
if (x1 == x2 && y1 == y2)
return (sect1 == sect2);
BFSSectorSearch search(sect1);
while (auto sec = search.GetNext())
{
const walltype* wal;
int cnt;
for (cnt=sec->wallnum,wal=sec->firstWall(); cnt>0; cnt--,wal++)
{
auto const wal2 = wal->point2Wall();
const int32_t x31 = wal->wall_int_pos().X-x1, x34 = wal->wall_int_pos().X-wal2->wall_int_pos().X;
const int32_t y31 = wal->wall_int_pos().Y-y1, y34 = wal->wall_int_pos().Y-wal2->wall_int_pos().Y;
int32_t x, y, z, t, bot;
int32_t cfz[2];
bot = y21*x34-x21*y34; if (bot <= 0) continue;
// XXX: OVERFLOW
t = y21*x31-x21*y31; if ((unsigned)t >= (unsigned)bot) continue;
t = y31*x34-x31*y34;
if ((unsigned)t >= (unsigned)bot)
{
continue;
}
if (!wal->twoSided() || wal->cstat & CSTAT_WALL_1WAY)
return 0;
t = DivScale(t,bot, 24);
x = x1 + MulScale(x21,t, 24);
y = y1 + MulScale(y21,t, 24);
z = z1 + MulScale(z21,t, 24);
int_getzsofslopeptr(sec, x,y, &cfz[0],&cfz[1]);
if (z <= cfz[0] || z >= cfz[1])
{
return 0;
}
auto nexts = wal->nextSector();
int_getzsofslopeptr(nexts, x,y, &cfz[0],&cfz[1]);
if (z <= cfz[0] || z >= cfz[1])
return 0;
search.Add(nexts);
}
}
return search.Check(sect2);
}
//
// neartag
//

View file

@ -541,6 +541,50 @@ sectortype* nextsectorneighborzptr(sectortype* sectp, double startz, int flags)
}
//==========================================================================
//
//
//
//==========================================================================
bool cansee(const DVector3& start, sectortype* sect1, const DVector3& end, sectortype* sect2)
{
if (!sect1 || !sect2) return false;
auto delta = end - start;
if (delta.XY().isZero())
return (sect1 == sect2);
BFSSectorSearch search(sect1);
while (auto sec = search.GetNext())
{
for (auto& wal : wallsofsector(sec))
{
double factor = InterceptLineSegments(start.X, start.Y, delta.X, delta.Y, wal.pos.X, wal.pos.Y, wal.delta().X, wal.delta().Y, nullptr, true);
if (factor <= 0 || factor >= 1) continue;
if (!wal.twoSided() || wal.cstat & CSTAT_WALL_1WAY)
return false;
auto spot = start + delta * factor;
double floorz, ceilz;
for (auto isec : { sec, wal.nextSector() })
{
getzsofslopeptr(isec, spot, &ceilz, &floorz);
if (spot.Z <= ceilz || spot.Z >= floorz)
return false;
}
search.Add(wal.nextSector());
}
}
return search.Check(sect2);
}
//==========================================================================
//
//

View file

@ -261,6 +261,8 @@ void loaddefinitionsfile(const char* fn, bool cumulative = false, bool maingrp =
bool calcChaseCamPos(DVector3& ppos, DCoreActor* pspr, sectortype** psectnum, DAngle ang, fixedhoriz horiz, double const interpfrac);
int getslopeval(sectortype* sect, const DVector3& pos, double bazez);
bool cansee(const DVector3& start, sectortype* sect1, const DVector3& end, sectortype* sect2);
@ -548,11 +550,11 @@ inline double InterceptVector(double v2x, double v2y, double v2dx, double v2dy,
}
// Essentially two InterceptVector calls. We can reduce the calculations because the denominators for both calculations only differ by their sign.
inline double InterceptLineSegments(double v2x, double v2y, double v2dx, double v2dy, double v1x, double v1y, double v1dx, double v1dy, double* pfactor1 = nullptr)
inline double InterceptLineSegments(double v2x, double v2y, double v2dx, double v2dy, double v1x, double v1y, double v1dx, double v1dy, double* pfactor1 = nullptr, bool forcansee = false)
{
double den = v1dy * v2dx - v1dx * v2dy;
if (den == 0)
if (den == 0 || (forcansee && den < 0)) // cansee does this added check here, aside from that its logic is virtually the same.
return 0; // parallel
// perform the division first for better parallelization.
@ -666,6 +668,12 @@ inline int32_t lintersect(const int32_t originX, const int32_t originY, const in
return result;
}
[[deprecated]]
inline int cansee(int x1, int y1, int z1, sectortype* sect1, int x2, int y2, int z2, sectortype* sect2)
{
return cansee(DVector3(x1 * inttoworld, y1 * inttoworld, z1 * zinttoworld), sect1, DVector3(x2 * inttoworld, y2 * inttoworld, z2 * zinttoworld), sect2);
}
#include "updatesector.h"