mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-22 20:21:13 +00:00
- float version of clipmove's slope sprite collector.
This could be simplified quite a bit by leveraging the info returned by GetFlatSpritePosition.
This commit is contained in:
parent
ede7a7ac12
commit
ea530cbc49
3 changed files with 58 additions and 69 deletions
|
@ -248,17 +248,12 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect,
|
||||||
TSectIterator<DCoreActor> it(dasect);
|
TSectIterator<DCoreActor> it(dasect);
|
||||||
while (auto actor = it.Next())
|
while (auto actor = it.Next())
|
||||||
{
|
{
|
||||||
const int32_t cstat = actor->spr.cstat;
|
int cstat = actor->spr.cstat;
|
||||||
|
|
||||||
if (actor->spr.cstat2 & CSTAT2_SPRITE_NOFIND) continue;
|
if (actor->spr.cstat2 & CSTAT2_SPRITE_NOFIND) continue;
|
||||||
if ((cstat&dasprclipmask) == 0)
|
if ((cstat & dasprclipmask) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto p1 = actor->int_pos().vec2;
|
|
||||||
|
|
||||||
CollisionBase obj;
|
|
||||||
obj.setSprite(actor);
|
|
||||||
|
|
||||||
switch (cstat & (CSTAT_SPRITE_ALIGNMENT_MASK))
|
switch (cstat & (CSTAT_SPRITE_ALIGNMENT_MASK))
|
||||||
{
|
{
|
||||||
case CSTAT_SPRITE_ALIGNMENT_FACING:
|
case CSTAT_SPRITE_ALIGNMENT_FACING:
|
||||||
|
@ -274,63 +269,7 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CSTAT_SPRITE_ALIGNMENT_SLOPE:
|
case CSTAT_SPRITE_ALIGNMENT_SLOPE:
|
||||||
{
|
processClipSlopeSprite(clip, actor);
|
||||||
|
|
||||||
if (!processClipFloorSprite(clip, actor)) continue;
|
|
||||||
int heinum = spriteGetSlope(actor);
|
|
||||||
|
|
||||||
if (heinum == 0) continue;
|
|
||||||
|
|
||||||
// the rest is for slope sprites only.
|
|
||||||
auto tex = TexMan.GetGameTexture(actor->spr.spritetexture());
|
|
||||||
const int32_t cosang = bcos(actor->int_ang());
|
|
||||||
const int32_t sinang = bsin(actor->int_ang());
|
|
||||||
vec2_t const span = { (int)tex->GetDisplayWidth(), (int)tex->GetDisplayHeight() };
|
|
||||||
vec2_t const repeat = { int(actor->spr.scale.X * scaletoint), int(actor->spr.scale.Y * scaletoint) };
|
|
||||||
vec2_t adjofs = { (int)tex->GetDisplayLeftOffset(), (int)tex->GetDisplayTopOffset() };
|
|
||||||
|
|
||||||
if (actor->spr.cstat & CSTAT_SPRITE_XFLIP)
|
|
||||||
adjofs.X = -adjofs.X;
|
|
||||||
|
|
||||||
if (actor->spr.cstat & CSTAT_SPRITE_YFLIP)
|
|
||||||
adjofs.Y = -adjofs.Y;
|
|
||||||
|
|
||||||
int32_t const centerx = ((span.X >> 1) + adjofs.X) * repeat.X;
|
|
||||||
int32_t const centery = ((span.Y >> 1) + adjofs.Y) * repeat.Y;
|
|
||||||
int32_t const rspanx = span.X * repeat.X;
|
|
||||||
int32_t const rspany = span.Y * repeat.Y;
|
|
||||||
int32_t const ratio = ksqrt(heinum * heinum + SLOPEVAL_FACTOR * SLOPEVAL_FACTOR);
|
|
||||||
int32_t zz[3] = { pos->Z, pos->Z + flordist, pos->Z - ceildist };
|
|
||||||
for (int k = 0; k < 3; k++)
|
|
||||||
{
|
|
||||||
int32_t jj = DivScale(actor->int_pos().Z - zz[k], heinum, 18);
|
|
||||||
int32_t jj2 = MulScale(jj, ratio, 12);
|
|
||||||
if (jj2 > (centery << 8) || jj2 < ((centery - rspany) << 8))
|
|
||||||
continue;
|
|
||||||
int32_t x1 = actor->int_pos().X + MulScale(sinang, centerx, 16) + MulScale(jj, cosang, 24);
|
|
||||||
int32_t y1 = actor->int_pos().Y - MulScale(cosang, centerx, 16) + MulScale(jj, sinang, 24);
|
|
||||||
int32_t x2 = x1 - MulScale(sinang, rspanx, 16);
|
|
||||||
int32_t y2 = y1 + MulScale(cosang, rspanx, 16);
|
|
||||||
|
|
||||||
vec2_t const v = { MulScale(bcos(actor->int_ang() - 256), walldist, 14),
|
|
||||||
MulScale(bsin(actor->int_ang() - 256), walldist, 14) };
|
|
||||||
|
|
||||||
if (clipinsideboxline(cent.X, cent.Y, x1, y1, x2, y2, rad) != 0)
|
|
||||||
{
|
|
||||||
if ((x1 - pos->X) * (y2 - pos->Y) >= (x2 - pos->X) * (y1 - pos->Y))
|
|
||||||
{
|
|
||||||
addclipline(x1 + v.X, y1 + v.Y, x2 + v.Y, y2 - v.X, obj, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((cstat & CSTAT_SPRITE_ONE_SIDE) != 0)
|
|
||||||
continue;
|
|
||||||
addclipline(x2 - v.X, y2 - v.Y, x1 - v.Y, y1 + v.X, obj, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (clipsectcnt < clipsectnum || clipspritecnt < clipspritenum);
|
} while (clipsectcnt < clipsectnum || clipspritecnt < clipspritenum);
|
||||||
|
|
|
@ -1403,14 +1403,13 @@ void processClipWallSprite(MoveClipper& clip, DCoreActor* actor)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
bool processClipFloorSprite(MoveClipper& clip, DCoreActor* actor)
|
bool processClipFloorSprite(MoveClipper& clip, DCoreActor* actor, DVector2* points, double* heights)
|
||||||
{
|
{
|
||||||
int heinum = spriteGetSlope(actor);
|
int heinum = spriteGetSlope(actor);
|
||||||
double sprz = spriteGetZOfSlopef(&actor->spr, actor->spr.pos.XY(), heinum);
|
double sprz = spriteGetZOfSlopef(&actor->spr, actor->spr.pos.XY(), heinum);
|
||||||
|
@ -1422,8 +1421,9 @@ bool processClipFloorSprite(MoveClipper& clip, DCoreActor* actor)
|
||||||
if ((clip.pos.Z > sprz) == ((actor->spr.cstat & CSTAT_SPRITE_YFLIP) == 0)) return false;
|
if ((clip.pos.Z > sprz) == ((actor->spr.cstat & CSTAT_SPRITE_YFLIP) == 0)) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DVector2 points[4];
|
DVector2 opoints[4];
|
||||||
GetFlatSpritePosition(actor, actor->spr.pos.XY(), points, nullptr);
|
if (!points) points = opoints;
|
||||||
|
GetFlatSpritePosition(actor, actor->spr.pos.XY(), points, heights);
|
||||||
|
|
||||||
auto offset = (actor->spr.Angles.Yaw - DAngle45).ToVector() * clip.walldist;
|
auto offset = (actor->spr.Angles.Yaw - DAngle45).ToVector() * clip.walldist;
|
||||||
|
|
||||||
|
@ -1464,6 +1464,55 @@ bool processClipFloorSprite(MoveClipper& clip, DCoreActor* actor)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
|
void processClipSlopeSprite(MoveClipper& clip, DCoreActor* actor)
|
||||||
|
{
|
||||||
|
auto spos = actor->spr.pos;
|
||||||
|
DVector2 points[4];
|
||||||
|
double heights[4];
|
||||||
|
DVector2 lpoints[2];
|
||||||
|
|
||||||
|
if (!processClipFloorSprite(clip, actor, points, heights)) return;
|
||||||
|
int heinum = spriteGetSlope(actor);
|
||||||
|
if (heinum == 0) return;
|
||||||
|
|
||||||
|
double zz[3] = { clip.pos.Z, clip.pos.Z + clip.floordist, clip.pos.Z - clip.ceilingdist };
|
||||||
|
|
||||||
|
CollisionBase objtype;
|
||||||
|
objtype.setSprite(actor);
|
||||||
|
|
||||||
|
for (int k = 0; k < 3; k++)
|
||||||
|
{
|
||||||
|
double factor = (zz[k] - heights[0]) / (heights[1] - heights[0]);
|
||||||
|
if (factor < 0 || factor > 1) continue; // sprite never hits the desired height.
|
||||||
|
auto dist = (points[1] - points[0]) * factor;
|
||||||
|
lpoints[0] = points[0] + dist;
|
||||||
|
lpoints[1] = points[3] + dist;
|
||||||
|
|
||||||
|
// 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 d = lpoints[1] - lpoints[0];
|
||||||
|
|
||||||
|
if (PointOnLineSide(clip.center.X, clip.center.Y, lpoints[0].X, lpoints[0].Y, d.X, d.Y) <= 0)
|
||||||
|
{
|
||||||
|
// in front
|
||||||
|
addClipLine(clip, lpoints[0] + offset, lpoints[1] + offset.Rotated90CW(), objtype);
|
||||||
|
}
|
||||||
|
else if (!(actor->spr.cstat & CSTAT_SPRITE_ONE_SIDE))
|
||||||
|
{
|
||||||
|
// behind
|
||||||
|
addClipLine(clip, lpoints[0] - offset, lpoints[1] + offset.Rotated90CCW(), objtype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
int FindBestSector(const DVector3& pos)
|
int FindBestSector(const DVector3& pos)
|
||||||
{
|
{
|
||||||
int bestnum = -1;
|
int bestnum = -1;
|
||||||
|
|
|
@ -261,7 +261,8 @@ void processClipWalls(MoveClipper& clip, sectortype* sec);
|
||||||
|
|
||||||
void processClipFaceSprite(MoveClipper& clip, DCoreActor* actor);
|
void processClipFaceSprite(MoveClipper& clip, DCoreActor* actor);
|
||||||
void processClipWallSprite(MoveClipper& clip, DCoreActor* actor);
|
void processClipWallSprite(MoveClipper& clip, DCoreActor* actor);
|
||||||
bool processClipFloorSprite(MoveClipper& clip, DCoreActor* actor);
|
bool processClipFloorSprite(MoveClipper& clip, DCoreActor* actor, DVector2* points = nullptr, double* heights = nullptr);
|
||||||
|
void processClipSlopeSprite(MoveClipper& clip, DCoreActor* actor);
|
||||||
int FindBestSector(const DVector3& pos);
|
int FindBestSector(const DVector3& pos);
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue