- moved the clip object storage into the clip object and floatified it.

This commit is contained in:
Christoph Oelckers 2022-10-23 21:58:20 +02:00
parent ea530cbc49
commit 3da1966cc7
4 changed files with 50 additions and 69 deletions

View file

@ -12,21 +12,11 @@
#define clip_h_
#define MAXCLIPSECTORS 512
#define MAXCLIPNUM 2048
#define CLIPCURBHEIGHT (1)
typedef struct
{
int32_t x1, y1, x2, y2;
} linetype;
extern int clipsectorlist[MAXCLIPSECTORS];
struct CollisionBase;
CollisionBase clipmove_(vec3_t *const pos, int *const sectnum, int32_t xvect, int32_t yvect, int32_t const walldist, int32_t const ceildist,
int32_t const flordist, uint32_t const cliptype, int clipmoveboxtracenum = 3) ATTRIBUTE((nonnull(1, 2)));
int pushmove_(vec3_t *const vect, int *const sectnum, int32_t const walldist, int32_t const ceildist, int32_t const flordist,
uint32_t const cliptype, bool clear = true) ATTRIBUTE((nonnull(1, 2)));
#endif

View file

@ -16,14 +16,9 @@
enum { MAXCLIPDIST = 1024 };
static int clipnum;
static linetype clipit[MAXCLIPNUM];
static int32_t clipsectnum, origclipsectnum, clipspritenum;
int clipsectorlist[MAXCLIPSECTORS];
static int origclipsectorlist[MAXCLIPSECTORS];
static CollisionBase clipobjectval[MAXCLIPNUM];
static uint8_t clipignore[(MAXCLIPNUM+7)>>3];
static int32_t rxi[8], ryi[8];
BitArray clipsectormap;
@ -50,7 +45,6 @@ static int clipinsideboxline(int x, int y, int x1, int y1, int x2, int y2, int w
return (int)IsCloseToLine(DVector2(x * inttoworld, y * inttoworld), DVector2(x1 * inttoworld, y1 * inttoworld), DVector2(x2 * inttoworld, y2 * inttoworld), walldist * inttoworld);
}
static int32_t clipmove_warned;
static inline void addclipsect(int const sectnum)
{
@ -59,35 +53,9 @@ static inline void addclipsect(int const sectnum)
clipsectormap.Set(sectnum);
clipsectorlist[clipsectnum++] = sectnum;
}
else
clipmove_warned |= 1;
}
static void addclipline(int32_t dax1, int32_t day1, int32_t dax2, int32_t day2, const CollisionBase& daoval, int nofix)
{
if (clipnum >= MAXCLIPNUM)
{
clipmove_warned |= 2;
return;
}
clipit[clipnum].x1 = dax1; clipit[clipnum].y1 = day1;
clipit[clipnum].x2 = dax2; clipit[clipnum].y2 = day2;
clipobjectval[clipnum] = daoval;
uint32_t const mask = (1 << (clipnum&7));
uint8_t &value = clipignore[clipnum>>3];
value = (value & ~mask) | (-nofix & mask);
clipnum++;
}
void addClipLine(MoveClipper& clip, const DVector2& start, const DVector2& end, const CollisionBase& daoval, int nofix)
{
addclipline(int(start.X * worldtoint), int(start.Y * worldtoint), int(end.X * worldtoint), int(end.Y * worldtoint), daoval, nofix);
}
void addClipSect(MoveClipper& clip, int sec)
{
if (!clipsectormap[sec])
@ -99,14 +67,14 @@ void addClipSect(MoveClipper& clip, int sec)
//
// raytrace (internal)
//
static inline int32_t cliptrace(vec2_t const pos, vec2_t * const goal)
static inline int32_t cliptrace(MoveClipper& clip, vec2_t const pos, vec2_t * const goal)
{
int32_t hitwall = -1;
for (int z=clipnum-1; z>=0; z--)
for (int z=clip.clipobjects.Size() - 1; z >= 0; z--)
{
vec2_t const p1 = { clipit[z].x1, clipit[z].y1 };
vec2_t const p2 = { clipit[z].x2, clipit[z].y2 };
vec2_t const p1 = { clip.clipobjects[z].x1(), clip.clipobjects[z].y1()};
vec2_t const p2 = { clip.clipobjects[z].x2(), clip.clipobjects[z].y2()};
vec2_t const area = { p2.X-p1.X, p2.Y-p1.Y };
int32_t topu = area.X*(pos.Y-p1.Y) - (pos.X-p1.X)*area.Y;
@ -152,10 +120,10 @@ static inline int32_t cliptrace(vec2_t const pos, vec2_t * const goal)
//
// keepaway (internal)
//
static inline void keepaway(int32_t *x, int32_t *y, int32_t w)
static inline void keepaway(MoveClipper& clip, int32_t *x, int32_t *y, int32_t w)
{
const int32_t x1 = clipit[w].x1, dx = clipit[w].x2-x1;
const int32_t y1 = clipit[w].y1, dy = clipit[w].y2-y1;
const int32_t x1 = clip.clipobjects[w].x1(), dx = clip.clipobjects[w].x2() - x1;
const int32_t y1 = clip.clipobjects[w].y1(), dy = clip.clipobjects[w].y2() - y1;
const int32_t ox = Sgn(-dy), oy = Sgn(dx);
uint8_t first = (abs(dx) <= abs(dy));
@ -180,9 +148,8 @@ static inline void keepaway(int32_t *x, int32_t *y, int32_t w)
CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect, int32_t yvect,
int32_t const walldist, int32_t const ceildist, int32_t const flordist, uint32_t const cliptype, int clipmoveboxtracenum)
{
CollisionBase b{};
if ((xvect|yvect) == 0 || *sectnum < 0)
return b;
return {};
int const initialsectnum = *sectnum;
@ -219,11 +186,8 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect,
clipsectorlist[0] = *sectnum;
clipsectnum = 1;
clipnum = 0;
clipspritenum = 0;
clipmove_warned = 0;
clipsectormap.Zero();
clipsectormap.Set(*sectnum);
@ -234,12 +198,6 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect,
////////// Walls //////////
processClipWalls(clip, &sector[dasect]);
if (clipmove_warned & 1)
Printf("clipsectnum >= MAXCLIPSECTORS!\n");
if (clipmove_warned & 2)
Printf("clipnum >= MAXCLIPNUM!\n");
////////// Sprites //////////
if (dasprclipmask==0)
@ -283,12 +241,12 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect,
{
if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE && (xvect|yvect))
{
for (int i=clipnum-1;i>=0;--i)
for (int i=clip.clipobjects.Size() - 1; i >= 0; --i)
{
if (!bitmap_test(clipignore, i) && clipinsideboxline(pos->X, pos->Y, clipit[i].x1, clipit[i].y1, clipit[i].x2, clipit[i].y2, walldist))
if (!clip.clipobjects[i].obj.exbits && clipinsideboxline(pos->X, pos->Y, clip.clipobjects[i].x1(), clip.clipobjects[i].y1(), clip.clipobjects[i].x2(), clip.clipobjects[i].y2(), walldist))
{
vec2_t const vec = pos->vec2;
keepaway(&pos->X, &pos->Y, i);
keepaway(clip, &pos->X, &pos->Y, i);
if (inside(pos->X * inttoworld, pos->Y * inttoworld, &sector[*sectnum]) != 1)
pos->vec2 = vec;
break;
@ -298,9 +256,9 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect,
vec2_t vec = goal;
if ((hitwall = cliptrace(pos->vec2, &vec)) >= 0)
if ((hitwall = cliptrace(clip, pos->vec2, &vec)) >= 0)
{
vec2_t const clipr = { clipit[hitwall].x2 - clipit[hitwall].x1, clipit[hitwall].y2 - clipit[hitwall].y1 };
vec2_t const clipr = { clip.clipobjects[hitwall].x2() - clip.clipobjects[hitwall].x1(), clip.clipobjects[hitwall].y2() - clip.clipobjects[hitwall].y1()};
// clamp to the max value we can utilize without reworking the scaling below
// this works around the overflow issue that affects dukedc2.map
int32_t const templl = (int32_t)clamp<int64_t>(((int64_t)clipr.X * clipr.X + (int64_t)clipr.Y * clipr.Y), INT32_MIN, INT32_MAX);
@ -323,7 +281,7 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect,
j = hitwalls[i];
int32_t tempint2;
tempint2 = DMulScale(clipit[j].x2-clipit[j].x1, move.X, clipit[j].y2-clipit[j].y1, move.Y, 6);
tempint2 = DMulScale(clip.clipobjects[j].x2() - clip.clipobjects[j].x1(), move.X, clip.clipobjects[j].y2() - clip.clipobjects[j].y1(), move.Y, 6);
if ((tempint ^ tempint2) < 0)
{
@ -337,12 +295,12 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect,
}
}
keepaway(&goal.X, &goal.Y, hitwall);
keepaway(clip, &goal.X, &goal.Y, hitwall);
xvect = (goal.X-vec.X)<<14;
yvect = (goal.Y-vec.Y)<<14;
if (cnt == clipmoveboxtracenum)
clipReturn = clipobjectval[hitwall];
clipReturn = clip.clipobjects[hitwall].obj;
hitwalls[cnt] = hitwall;
}

View file

@ -1230,6 +1230,21 @@ int pushmove(DVector3& pos, sectortype** pSect, double walldist, double ceildist
//
//==========================================================================
void addClipLine(MoveClipper& clip, const DVector2& start, const DVector2& end, const CollisionBase& daoval, int nofix)
{
clip.clipobjects.Reserve(1);
auto& c = clip.clipobjects.Last();
c.obj = daoval;
c.obj.exbits = nofix; // hijack this unused field instead of creating an additional bit array.
c.line = { start, end };
}
//==========================================================================
//
//
//
//==========================================================================
static int checkClipWall(const MoveClipper& clip, walltype* wal)
{
auto wal2 = wal->point2Wall();
@ -1491,7 +1506,7 @@ void processClipSlopeSprite(MoveClipper& clip, DCoreActor* actor)
// The rest is just the same as the main part of the wall sprite collector.
if (IsCloseToLine(clip.center, lpoints[0], lpoints[1], clip.movedist) == EClose::Outside) continue; // out of reach
auto offset = (actor->spr.angle - DAngle45).ToVector() * clip.walldist;
auto offset = (actor->spr.Angles.Yaw - DAngle45).ToVector() * clip.walldist;
auto d = lpoints[1] - lpoints[0];
if (PointOnLineSide(clip.center.X, clip.center.Y, lpoints[0].X, lpoints[0].Y, d.X, d.Y) <= 0)

View file

@ -240,6 +240,23 @@ struct ClipRect
DVector2 max;
};
struct ClipLine
{
DVector2 start, end;
};
struct ClipObject
{
CollisionBase obj;
ClipLine line;
// we still need these...
int x1() const { return int(line.start.X * worldtoint); }
int y1() const { return int(line.start.Y * worldtoint); }
int x2() const { return int(line.end.X * worldtoint); }
int y2() const { return int(line.end.Y * worldtoint); }
};
struct MoveClipper
{
DVector3 pos;
@ -252,6 +269,7 @@ struct MoveClipper
double floordist;
double walldist;
double movedist;
TArray<ClipObject> clipobjects;
};
void addClipLine(MoveClipper& clip, const DVector2& start, const DVector2& end, const CollisionBase& daoval, int nofix = false);