mirror of
https://github.com/ZDoom/Raze.git
synced 2024-12-01 08:31:30 +00:00
- new floating point version of clipmove's wall sprite checker.
This commit is contained in:
parent
5e4f638e83
commit
38b49e1a09
3 changed files with 64 additions and 52 deletions
|
@ -43,16 +43,6 @@ static inline int bcos(const int ang)
|
|||
inline uint8_t bitmap_test(uint8_t const* const ptr, int const n) { return ptr[n >> 3] & (1 << (n & 7)); }
|
||||
|
||||
|
||||
// x1, y1: in/out
|
||||
// rest x/y: out
|
||||
static inline void get_wallspr_points(DCoreActor* actor, int32_t *x1, int32_t *x2, int32_t *y1, int32_t *y2)
|
||||
{
|
||||
DVector2 out[2];
|
||||
GetWallSpritePosition(&actor->spr, DVector2(*x1 * inttoworld, *y1 * inttoworld), out);
|
||||
*x1 = int(out[0].X * worldtoint); *y1 = int(out[0].Y * worldtoint);
|
||||
*x2 = int(out[1].X * worldtoint); *y2 = int(out[1].Y * worldtoint);
|
||||
}
|
||||
|
||||
// x1, y1: in/out
|
||||
// rest x/y: out
|
||||
static inline void get_floorspr_points(DCoreActor *spr, int32_t px, int32_t py,
|
||||
|
@ -241,6 +231,10 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect,
|
|||
clip.ceilingdist = ceildist * zinttoworld;
|
||||
clip.floordist = flordist * zinttoworld;
|
||||
clip.walldist = walldist * inttoworld;
|
||||
clip.pos = { pos->X * inttoworld, pos->Y * inttoworld, pos->Z * zinttoworld };
|
||||
clip.dest = { goal.X * inttoworld, goal.Y * inttoworld };
|
||||
clip.center = (clip.pos.XY() + clip.dest) * 0.5;
|
||||
clip.movedist = clip.moveDelta.Length() + clip.walldist + 0.5 + MAXCLIPDIST * inttoworld;
|
||||
|
||||
int clipsectcnt = 0;
|
||||
int clipspritecnt = 0;
|
||||
|
@ -259,7 +253,6 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect,
|
|||
do
|
||||
{
|
||||
int const dasect = clipsectorlist[clipsectcnt++];
|
||||
clip.pos = { pos->X * inttoworld, pos->Y * inttoworld, pos->Z * zinttoworld };
|
||||
|
||||
////////// Walls //////////
|
||||
processClipWalls(clip, §or[dasect]);
|
||||
|
@ -292,43 +285,11 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect,
|
|||
switch (cstat & (CSTAT_SPRITE_ALIGNMENT_MASK))
|
||||
{
|
||||
case CSTAT_SPRITE_ALIGNMENT_FACING:
|
||||
processClipFaceSprites(clip, actor);
|
||||
processClipFaceSprite(clip, actor);
|
||||
break;
|
||||
|
||||
case CSTAT_SPRITE_ALIGNMENT_WALL:
|
||||
{
|
||||
double height_, daz_ = actor->spr.pos.Z + actor->GetOffsetAndHeight(height_);
|
||||
int height = int(height_ * zworldtoint), daz = int(daz_ * zworldtoint);
|
||||
|
||||
if (pos->Z > daz-height-flordist && pos->Z < daz+ceildist)
|
||||
{
|
||||
vec2_t p2;
|
||||
|
||||
get_wallspr_points(actor, &p1.X, &p2.X, &p1.Y, &p2.Y);
|
||||
|
||||
if (clipinsideboxline(cent.X, cent.Y, p1.X, p1.Y, p2.X, p2.Y, rad) != 0)
|
||||
{
|
||||
vec2_t v = { MulScale(bcos(actor->int_ang() + 256), walldist, 14),
|
||||
MulScale(bsin(actor->int_ang() + 256), walldist, 14) };
|
||||
|
||||
if ((p1.X-pos->X) * (p2.Y-pos->Y) >= (p2.X-pos->X) * (p1.Y-pos->Y)) // Front
|
||||
addclipline(p1.X+v.X, p1.Y+v.Y, p2.X+v.Y, p2.Y-v.X, obj, false);
|
||||
else
|
||||
{
|
||||
if ((cstat & CSTAT_SPRITE_ONE_SIDE) != 0)
|
||||
continue;
|
||||
addclipline(p2.X-v.X, p2.Y-v.Y, p1.X-v.Y, p1.Y+v.X, obj, false);
|
||||
}
|
||||
|
||||
//Side blocker
|
||||
if ((p2.X-p1.X) * (pos->X-p1.X)+(p2.Y-p1.Y) * (pos->Y-p1.Y) < 0)
|
||||
addclipline(p1.X-v.Y, p1.Y+v.X, p1.X+v.X, p1.Y+v.Y, obj, true);
|
||||
else if ((p1.X-p2.X) * (pos->X-p2.X)+(p1.Y-p2.Y) * (pos->Y-p2.Y) < 0)
|
||||
addclipline(p2.X+v.Y, p2.Y-v.X, p2.X-v.X, p2.Y-v.Y, obj, true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
processClipWallSprite(clip, actor);
|
||||
|
||||
case CSTAT_SPRITE_ALIGNMENT_FLOOR:
|
||||
case CSTAT_SPRITE_ALIGNMENT_SLOPE:
|
||||
|
|
|
@ -1269,11 +1269,11 @@ static int checkClipWall(const MoveClipper& clip, walltype* wal)
|
|||
|
||||
static void addPointToClipList(MoveClipper& clip, const DVector2& pos, double radius, CollisionBase& objtype)
|
||||
{
|
||||
double waldist = (clip.moveDelta.X < 0)? radius : -radius;
|
||||
addClipLine(clip, pos + DVector2(waldist, waldist), pos + DVector2(waldist, -waldist), objtype);
|
||||
double waldistx = (clip.moveDelta.X < 0)? radius : -radius;
|
||||
addClipLine(clip, pos + DVector2(waldistx, waldistx), pos + DVector2(waldistx, -waldistx), objtype);
|
||||
|
||||
waldist = (clip.moveDelta.Y < 0) ? radius : -radius;
|
||||
addClipLine(clip, pos + DVector2(-waldist, waldist), pos + DVector2(waldist, waldist), objtype);
|
||||
double waldisty = (clip.moveDelta.Y < 0) ? radius : -radius;
|
||||
addClipLine(clip, pos + DVector2(-waldisty, waldisty), pos + DVector2(waldisty, waldisty), objtype);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1344,7 +1344,7 @@ void processClipWalls(MoveClipper& clip, sectortype* sec)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void processClipFaceSprites(MoveClipper& clip, DCoreActor* actor)
|
||||
void processClipFaceSprite(MoveClipper& clip, DCoreActor* actor)
|
||||
{
|
||||
auto spos = actor->spr.pos;
|
||||
if (!PointInRect(spos.XY(), clip.rect.min, clip.rect.max)) return; // are we outside this sprite's bounding box?
|
||||
|
@ -1368,6 +1368,54 @@ void processClipFaceSprites(MoveClipper& clip, DCoreActor* actor)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void processClipWallSprite(MoveClipper& clip, DCoreActor* actor)
|
||||
{
|
||||
auto spos = actor->spr.pos;
|
||||
double height, z = spos.Z + actor->GetOffsetAndHeight(height);
|
||||
|
||||
if (clip.pos.Z <= z - height - clip.floordist) return; // are we above the sprite?
|
||||
if (clip.pos.Z >= z + clip.ceilingdist) return; // are we below the sprite?
|
||||
|
||||
DVector2 points[2];
|
||||
GetWallSpritePosition(&actor->spr, actor->spr.pos.XY(), points, false);
|
||||
|
||||
if (IsCloseToLine(clip.center, points[0], points[1], clip.movedist) == EClose::Outside) return; // out of reach
|
||||
|
||||
CollisionBase objtype;
|
||||
objtype.setSprite(actor);
|
||||
|
||||
auto offset = (actor->spr.Angles.Yaw + DAngle45).ToVector() * clip.walldist; // Ok, why 45°?
|
||||
|
||||
auto d = points[1] - points[0];
|
||||
if (PointOnLineSide(clip.pos.X, clip.pos.Y, points[0].X, points[0].Y, d.X, d.Y) <= 0)
|
||||
{
|
||||
// in front
|
||||
addClipLine(clip, points[0] + offset, points[1] + offset.Rotated90CW(), objtype);
|
||||
}
|
||||
else if (!(actor->spr.cstat & CSTAT_SPRITE_ONE_SIDE))
|
||||
{
|
||||
// behind
|
||||
addClipLine(clip, points[0] - offset, points[1] + offset.Rotated90CCW(), objtype);
|
||||
}
|
||||
else return; // one-sided wall sprite from the back side does not count.
|
||||
|
||||
if (d.dot(clip.pos.XY() - points[0]) < 0)
|
||||
{
|
||||
addClipLine(clip, points[0] + offset.Rotated90CCW(), points[0] + offset, objtype, true);
|
||||
}
|
||||
else if (d.dot(clip.pos.XY() - points[1]) > 0)
|
||||
{
|
||||
addClipLine(clip, points[1] + offset.Rotated90CW(), points[1] - offset, objtype, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int FindBestSector(const DVector3& pos)
|
||||
{
|
||||
int bestnum = -1;
|
||||
|
|
|
@ -243,13 +243,15 @@ struct ClipRect
|
|||
struct MoveClipper
|
||||
{
|
||||
DVector3 pos;
|
||||
DVector2 pest;
|
||||
DVector2 dest;
|
||||
DVector2 center;
|
||||
DVector2 moveDelta;
|
||||
ClipRect rect;
|
||||
EWallFlags wallflags;
|
||||
double ceilingdist;
|
||||
double floordist;
|
||||
double walldist;
|
||||
double movedist;
|
||||
};
|
||||
|
||||
void addClipLine(MoveClipper& clip, const DVector2& start, const DVector2& end, const CollisionBase& daoval, int nofix = false);
|
||||
|
@ -257,7 +259,8 @@ void addClipSect(MoveClipper& clip, int sec);
|
|||
|
||||
void processClipWalls(MoveClipper& clip, sectortype* sec);
|
||||
|
||||
void processClipFaceSprites(MoveClipper& clip, DCoreActor* actor);
|
||||
void processClipFaceSprite(MoveClipper& clip, DCoreActor* actor);
|
||||
void processClipWallSprite(MoveClipper& clip, DCoreActor* actor);
|
||||
int FindBestSector(const DVector3& pos);
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue