mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-29 07:21:54 +00:00
- new floating point version of clipmove's wall sprite checker.
This commit is contained in:
parent
4acbfef1dc
commit
3ea993140b
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)); }
|
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
|
// x1, y1: in/out
|
||||||
// rest x/y: out
|
// rest x/y: out
|
||||||
static inline void get_floorspr_points(DCoreActor *spr, int32_t px, int32_t py,
|
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.ceilingdist = ceildist * zinttoworld;
|
||||||
clip.floordist = flordist * zinttoworld;
|
clip.floordist = flordist * zinttoworld;
|
||||||
clip.walldist = walldist * inttoworld;
|
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 clipsectcnt = 0;
|
||||||
int clipspritecnt = 0;
|
int clipspritecnt = 0;
|
||||||
|
@ -259,7 +253,6 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect,
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
int const dasect = clipsectorlist[clipsectcnt++];
|
int const dasect = clipsectorlist[clipsectcnt++];
|
||||||
clip.pos = { pos->X * inttoworld, pos->Y * inttoworld, pos->Z * zinttoworld };
|
|
||||||
|
|
||||||
////////// Walls //////////
|
////////// Walls //////////
|
||||||
processClipWalls(clip, §or[dasect]);
|
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))
|
switch (cstat & (CSTAT_SPRITE_ALIGNMENT_MASK))
|
||||||
{
|
{
|
||||||
case CSTAT_SPRITE_ALIGNMENT_FACING:
|
case CSTAT_SPRITE_ALIGNMENT_FACING:
|
||||||
processClipFaceSprites(clip, actor);
|
processClipFaceSprite(clip, actor);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CSTAT_SPRITE_ALIGNMENT_WALL:
|
case CSTAT_SPRITE_ALIGNMENT_WALL:
|
||||||
{
|
processClipWallSprite(clip, actor);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CSTAT_SPRITE_ALIGNMENT_FLOOR:
|
case CSTAT_SPRITE_ALIGNMENT_FLOOR:
|
||||||
case CSTAT_SPRITE_ALIGNMENT_SLOPE:
|
case CSTAT_SPRITE_ALIGNMENT_SLOPE:
|
||||||
|
|
|
@ -1264,11 +1264,11 @@ static int checkClipWall(const MoveClipper& clip, walltype* wal)
|
||||||
|
|
||||||
static void addPointToClipList(MoveClipper& clip, const DVector2& pos, double radius, CollisionBase& objtype)
|
static void addPointToClipList(MoveClipper& clip, const DVector2& pos, double radius, CollisionBase& objtype)
|
||||||
{
|
{
|
||||||
double waldist = (clip.moveDelta.X < 0)? radius : -radius;
|
double waldistx = (clip.moveDelta.X < 0)? radius : -radius;
|
||||||
addClipLine(clip, pos + DVector2(waldist, waldist), pos + DVector2(waldist, -waldist), objtype);
|
addClipLine(clip, pos + DVector2(waldistx, waldistx), pos + DVector2(waldistx, -waldistx), objtype);
|
||||||
|
|
||||||
waldist = (clip.moveDelta.Y < 0) ? radius : -radius;
|
double waldisty = (clip.moveDelta.Y < 0) ? radius : -radius;
|
||||||
addClipLine(clip, pos + DVector2(-waldist, waldist), pos + DVector2(waldist, waldist), objtype);
|
addClipLine(clip, pos + DVector2(-waldisty, waldisty), pos + DVector2(waldisty, waldisty), objtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -1339,7 +1339,7 @@ void processClipWalls(MoveClipper& clip, sectortype* sec)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void processClipFaceSprites(MoveClipper& clip, DCoreActor* actor)
|
void processClipFaceSprite(MoveClipper& clip, DCoreActor* actor)
|
||||||
{
|
{
|
||||||
auto spos = actor->spr.pos;
|
auto spos = actor->spr.pos;
|
||||||
if (!PointInRect(spos.XY(), clip.rect.min, clip.rect.max)) return; // are we outside this sprite's bounding box?
|
if (!PointInRect(spos.XY(), clip.rect.min, clip.rect.max)) return; // are we outside this sprite's bounding box?
|
||||||
|
@ -1363,6 +1363,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 FindBestSector(const DVector3& pos)
|
||||||
{
|
{
|
||||||
int bestnum = -1;
|
int bestnum = -1;
|
||||||
|
|
|
@ -243,13 +243,15 @@ struct ClipRect
|
||||||
struct MoveClipper
|
struct MoveClipper
|
||||||
{
|
{
|
||||||
DVector3 pos;
|
DVector3 pos;
|
||||||
DVector2 pest;
|
DVector2 dest;
|
||||||
|
DVector2 center;
|
||||||
DVector2 moveDelta;
|
DVector2 moveDelta;
|
||||||
ClipRect rect;
|
ClipRect rect;
|
||||||
EWallFlags wallflags;
|
EWallFlags wallflags;
|
||||||
double ceilingdist;
|
double ceilingdist;
|
||||||
double floordist;
|
double floordist;
|
||||||
double walldist;
|
double walldist;
|
||||||
|
double movedist;
|
||||||
};
|
};
|
||||||
|
|
||||||
void addClipLine(MoveClipper& clip, const DVector2& start, const DVector2& end, const CollisionBase& daoval, int nofix = false);
|
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 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);
|
int FindBestSector(const DVector3& pos);
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue