mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-22 12:11:17 +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);
|
||||
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 ((cstat&dasprclipmask) == 0)
|
||||
if ((cstat & dasprclipmask) == 0)
|
||||
continue;
|
||||
|
||||
auto p1 = actor->int_pos().vec2;
|
||||
|
||||
CollisionBase obj;
|
||||
obj.setSprite(actor);
|
||||
|
||||
switch (cstat & (CSTAT_SPRITE_ALIGNMENT_MASK))
|
||||
{
|
||||
case CSTAT_SPRITE_ALIGNMENT_FACING:
|
||||
|
@ -274,63 +269,7 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect,
|
|||
break;
|
||||
|
||||
case CSTAT_SPRITE_ALIGNMENT_SLOPE:
|
||||
{
|
||||
|
||||
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;
|
||||
}
|
||||
processClipSlopeSprite(clip, actor);
|
||||
}
|
||||
}
|
||||
} 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);
|
||||
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;
|
||||
}
|
||||
|
||||
DVector2 points[4];
|
||||
GetFlatSpritePosition(actor, actor->spr.pos.XY(), points, nullptr);
|
||||
DVector2 opoints[4];
|
||||
if (!points) points = opoints;
|
||||
GetFlatSpritePosition(actor, actor->spr.pos.XY(), points, heights);
|
||||
|
||||
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 bestnum = -1;
|
||||
|
|
|
@ -261,7 +261,8 @@ void processClipWalls(MoveClipper& clip, sectortype* sec);
|
|||
|
||||
void processClipFaceSprite(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);
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue