- doFurniture floatified and inside rewritten as a floating point algorithm that works without bit masking.

This commit is contained in:
Christoph Oelckers 2022-01-29 09:29:01 +01:00
parent 4d38f62a14
commit 7374364527
5 changed files with 84 additions and 93 deletions

View file

@ -164,7 +164,7 @@ int hitscan(const vec3_t& start, const sectortype* startsect, const vec3_t& dire
void neartag(const vec3_t& pos, sectortype* sect, int angle, HitInfoBase& result, int neartagrange, int tagsearch);
int cansee(int x1, int y1, int z1, sectortype* sect1, int x2, int y2, int z2, sectortype* sect2);
int32_t inside(int32_t x, int32_t y, const sectortype* sectnum);
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);
@ -326,10 +326,6 @@ extern int skiptile;
static vec2_t const zerovec = { 0, 0 };
inline int inside_p(int32_t const x, int32_t const y, int const sectnum) { return (sectnum >= 0 && inside(x, y, &sector[sectnum]) == 1); }
// same as above but with the same signature as inside_z_p for passing to updatesectorneighborz.
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); }
#define SET_AND_RETURN(Lval, Rval) \
do \
{ \

View file

@ -284,37 +284,6 @@ int32_t rintersect(int32_t x1, int32_t y1, int32_t z1,
return t;
}
//
// 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, const sectortype* sect)
{
if (sect)
{
unsigned cnt = 0;
vec2_t xy = { x, y };
for(auto& wal : wallsofsector(sect))
{
vec2_t v1 = wal.wall_int_pos() - xy;
vec2_t v2 = wal.point2Wall()->wall_int_pos() - xy;
// 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);
}
return cnt>>31;
}
return -1;
}
int32_t getangle(int32_t xvect, int32_t yvect)
{

View file

@ -435,6 +435,38 @@ DVector2 rotatepoint(const DVector2& pivot, const DVector2& point, binangle angl
//
//==========================================================================
int inside(double x, double y, const sectortype* sect)
{
if (sect)
{
double acc = 1;
for (auto& wal : wallsofsector(sect))
{
double xs = (wal.pos.X - x);
double ys = (wal.pos.Y - y);
auto wal2 = wal.point2Wall();
double xe = (wal2->pos.X - x);
double ye = (wal2->pos.Y - y);
if ((ys * ye) < 0)
{
double val;
if ((xs * xe) >= 0) val = xs;
else val = (xs * ye - xe * ys) * ye;
acc *= val;
}
}
return acc < 0;
}
return -1;
}
//==========================================================================
//
//
//
//==========================================================================
tspritetype* renderAddTsprite(tspritetype* tsprite, int& spritesortcnt, DCoreActor* actor)
{
validateTSpriteSize(tsprite, spritesortcnt);

View file

@ -171,6 +171,8 @@ bool sectorsConnected(int sect1, int sect2);
void dragpoint(walltype* wal, int newx, int newy);
void dragpoint(walltype* wal, const DVector2& pos);
DVector2 rotatepoint(const DVector2& pivot, const DVector2& point, binangle angle);
int32_t inside(double x, double y, const sectortype* sect);
// y is negated so that the orientation is the same as in GZDoom, in order to use its utilities.
// The render code should NOT use Build coordinates for anything!
@ -301,6 +303,17 @@ inline int32_t tspriteGetZOfSlope(const tspritetype* tspr, int dax, int day)
return tspr->pos.Z + MulScale(heinum, j, 18);
}
inline int inside(int x, int y, const sectortype* sect)
{
return inside(x * inttoworld, y * inttoworld, 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); }
inline int I_GetBuildTime()
{

View file

@ -2758,28 +2758,15 @@ void dofurniture(walltype* wlwal, sectortype* sectp, int snum)
{
assert(wlwal->twoSided());
auto nextsect = wlwal->nextSector();
int var_C;
int x;
int y;
int min_x;
int min_y;
int max_x;
int max_y;
int ins;
int var_cx;
var_C = 1;
max_x = max_y = -0x20000;
min_x = min_y = 0x20000;
var_cx = sectp->hitag;
if (var_cx > 16)
var_cx = 16;
else if (var_cx == 0)
var_cx = 4;
for(auto& wal : wallsofsector(nextsect))
double movestep = min(sectp->hitag * maptoworld, 1.);
if (movestep == 0) movestep = 4 * maptoworld;
double max_x = INT32_MIN, max_y = INT32_MIN, min_x = INT32_MAX, min_y = INT32_MAX;
for (auto& wal : wallsofsector(sectp))
{
x = wal.wall_int_pos().X;
y = wal.wall_int_pos().Y;
double x = wal.pos.X;
double y = wal.pos.Y;
if (x > max_x)
max_x = x;
if (y > max_y)
@ -2789,22 +2776,18 @@ void dofurniture(walltype* wlwal, sectortype* sectp, int snum)
if (y < min_y)
min_y = y;
}
max_x += var_cx + 1;
max_y += var_cx + 1;
min_x -= var_cx + 1;
min_y -= var_cx + 1;
ins = inside(max_x, max_y, sectp);
if (!ins)
var_C = 0;
ins = inside(max_x, min_y, sectp);
if (!ins)
var_C = 0;
ins = inside(min_x, min_y, sectp);
if (!ins)
var_C = 0;
ins = inside(min_x, max_y, sectp);
if (!ins)
var_C = 0;
double margin = movestep + maptoworld;
max_x += margin;
max_y += margin;
min_x -= margin;
min_y -= margin;
int pos_ok = 1;
if (!inside(max_x, max_y, sectp) ||
!inside(max_x, min_y, sectp) ||
!inside(min_x, min_y, sectp) ||
!inside(min_x, max_y, sectp))
pos_ok = 0;
for (auto& wal : wallsofsector(nextsect))
{
@ -2822,31 +2805,30 @@ void dofurniture(walltype* wlwal, sectortype* sectp, int snum)
}
}
if (var_C)
if (pos_ok)
{
if (S_CheckActorSoundPlaying(ps[snum].GetActor(), 389) == 0)
S_PlayActorSound(389, ps[snum].GetActor());
for(auto& wal : wallsofsector(nextsect))
{
x = wal.wall_int_pos().X;
y = wal.wall_int_pos().Y;
auto vec = wal.pos;
switch (wlwal->lotag)
{
case 42:
y = wal.wall_int_pos().Y + var_cx;
dragpoint(&wal, x, y);
vec.Y += movestep;
dragpoint(&wal, vec);
break;
case 41:
x = wal.wall_int_pos().X - var_cx;
dragpoint(&wal, x, y);
vec.X -= movestep;
dragpoint(&wal, vec);
break;
case 40:
y = wal.wall_int_pos().Y - var_cx;
dragpoint(&wal, x, y);
vec.Y -= movestep;
dragpoint(&wal, vec);
break;
case 43:
x = wal.wall_int_pos().X + var_cx;
dragpoint(&wal, x, y);
vec.X += movestep;
dragpoint(&wal, vec);
break;
}
}
@ -2855,25 +2837,24 @@ void dofurniture(walltype* wlwal, sectortype* sectp, int snum)
{
for(auto& wal : wallsofsector(nextsect))
{
x = wal.wall_int_pos().X;
y = wal.wall_int_pos().Y;
auto vec = wal.pos;
switch (wlwal->lotag)
{
case 42:
y = wal.wall_int_pos().Y - (var_cx - 2);
dragpoint(&wal, x, y);
vec.Y -= movestep - 2;
dragpoint(&wal, vec);
break;
case 41:
x = wal.wall_int_pos().X + (var_cx - 2);
dragpoint(&wal, x, y);
vec.X += movestep - 2;
dragpoint(&wal, vec);
break;
case 40:
y = wal.wall_int_pos().Y + (var_cx - 2);
dragpoint(&wal, x, y);
vec.Y += movestep - 2;
dragpoint(&wal, vec);
break;
case 43:
x = wal.wall_int_pos().X - (var_cx - 2);
dragpoint(&wal, x, y);
vec.X -= movestep - 2;
dragpoint(&wal, vec);
break;
}
}