mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-15 08:52:00 +00:00
- doFurniture floatified and inside rewritten as a floating point algorithm that works without bit masking.
This commit is contained in:
parent
4d38f62a14
commit
7374364527
5 changed files with 84 additions and 93 deletions
|
@ -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, §or[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 \
|
||||
{ \
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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, §or[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()
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue