mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-11 15:22:15 +00:00
- floatified P_CheckSlopeWalk. It should be noted that this function is one place where full double precision is too high and needed to be truncated.
This commit is contained in:
parent
26ff2f73d7
commit
23d311dd04
3 changed files with 55 additions and 44 deletions
|
@ -445,12 +445,14 @@ double P_GetFriction(const AActor *mo, double *frictionfactor);
|
||||||
bool Check_Sides(AActor *, int, int); // phares
|
bool Check_Sides(AActor *, int, int); // phares
|
||||||
|
|
||||||
// [RH]
|
// [RH]
|
||||||
const secplane_t * P_CheckSlopeWalk (AActor *actor, fixed_t &xmove, fixed_t &ymove);
|
const secplane_t * P_CheckSlopeWalk(AActor *actor, DVector2 &move);
|
||||||
inline const secplane_t * P_CheckSlopeWalk(AActor *actor, DVector2 &move)
|
|
||||||
|
inline const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymove)
|
||||||
{
|
{
|
||||||
fixedvec2 mov = { FLOAT2FIXED(move.X), FLOAT2FIXED(move.Y) };
|
DVector2 move = { FIXED2DBL(xmove), FIXED2DBL(ymove) };
|
||||||
const secplane_t *ret = P_CheckSlopeWalk(actor, mov.x, mov.y);
|
const secplane_t *ret = P_CheckSlopeWalk(actor, move);
|
||||||
move = { FIXED2DBL(mov.x), FIXED2DBL(mov.y) };
|
xmove = FLOAT2FIXED(move.X);
|
||||||
|
ymove = FLOAT2FIXED(move.Y);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2880,7 +2880,7 @@ void P_SlideMove(AActor *mo, const DVector2 &pos, int numsteps)
|
||||||
//
|
//
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymove)
|
const secplane_t * P_CheckSlopeWalk(AActor *actor, DVector2 &move)
|
||||||
{
|
{
|
||||||
static secplane_t copyplane;
|
static secplane_t copyplane;
|
||||||
if (actor->flags & MF_NOGRAVITY)
|
if (actor->flags & MF_NOGRAVITY)
|
||||||
|
@ -2888,21 +2888,20 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fixedvec3 pos = actor->_f_PosRelative(actor->floorsector);
|
DVector3 pos = actor->PosRelative(actor->floorsector);
|
||||||
const secplane_t *plane = &actor->floorsector->floorplane;
|
const secplane_t *plane = &actor->floorsector->floorplane;
|
||||||
fixed_t planezhere = plane->ZatPoint(pos);
|
double planezhere = plane->ZatPoint(pos);
|
||||||
|
|
||||||
for (unsigned int i = 0; i<actor->floorsector->e->XFloor.ffloors.Size(); i++)
|
for (auto rover : actor->floorsector->e->XFloor.ffloors)
|
||||||
{
|
{
|
||||||
F3DFloor * rover = actor->floorsector->e->XFloor.ffloors[i];
|
|
||||||
if (!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue;
|
if (!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue;
|
||||||
|
|
||||||
fixed_t thisplanez = rover->top.plane->ZatPoint(pos);
|
double thisplanez = rover->top.plane->ZatPoint(pos);
|
||||||
|
|
||||||
if (thisplanez>planezhere && thisplanez <= actor->_f_Z() + actor->_f_MaxStepHeight())
|
if (thisplanez > planezhere && thisplanez <= actor->Z() + actor->MaxStepHeight)
|
||||||
{
|
{
|
||||||
copyplane = *rover->top.plane;
|
copyplane = *rover->top.plane;
|
||||||
if (copyplane.c<0) copyplane.FlipVert();
|
if (copyplane.c < 0) copyplane.FlipVert();
|
||||||
plane = ©plane;
|
plane = ©plane;
|
||||||
planezhere = thisplanez;
|
planezhere = thisplanez;
|
||||||
}
|
}
|
||||||
|
@ -2910,17 +2909,16 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov
|
||||||
|
|
||||||
if (actor->floorsector != actor->Sector)
|
if (actor->floorsector != actor->Sector)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i<actor->Sector->e->XFloor.ffloors.Size(); i++)
|
for (auto rover : actor->Sector->e->XFloor.ffloors)
|
||||||
{
|
{
|
||||||
F3DFloor * rover = actor->Sector->e->XFloor.ffloors[i];
|
|
||||||
if (!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue;
|
if (!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue;
|
||||||
|
|
||||||
fixed_t thisplanez = rover->top.plane->ZatPoint(actor);
|
double thisplanez = rover->top.plane->ZatPointF(actor);
|
||||||
|
|
||||||
if (thisplanez>planezhere && thisplanez <= actor->_f_Z() + actor->_f_MaxStepHeight())
|
if (thisplanez > planezhere && thisplanez <= actor->Z() + actor->MaxStepHeight)
|
||||||
{
|
{
|
||||||
copyplane = *rover->top.plane;
|
copyplane = *rover->top.plane;
|
||||||
if (copyplane.c<0) copyplane.FlipVert();
|
if (copyplane.c < 0) copyplane.FlipVert();
|
||||||
plane = ©plane;
|
plane = ©plane;
|
||||||
planezhere = thisplanez;
|
planezhere = thisplanez;
|
||||||
}
|
}
|
||||||
|
@ -2930,23 +2928,22 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov
|
||||||
if (actor->floorsector != actor->Sector)
|
if (actor->floorsector != actor->Sector)
|
||||||
{
|
{
|
||||||
// this additional check prevents sliding on sloped dropoffs
|
// this additional check prevents sliding on sloped dropoffs
|
||||||
if (planezhere>actor->_f_floorz() + 4 * FRACUNIT)
|
if (planezhere>actor->floorz + 4)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actor->_f_Z() - planezhere > FRACUNIT)
|
if (actor->Z() - planezhere > 1)
|
||||||
{ // not on floor
|
{ // not on floor
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((plane->a | plane->b) != 0)
|
if (plane->isSlope())
|
||||||
{
|
{
|
||||||
fixed_t destx, desty;
|
DVector2 dest;
|
||||||
fixed_t t;
|
double t;
|
||||||
|
|
||||||
destx = actor->_f_X() + xmove;
|
dest = actor->Pos() + move;
|
||||||
desty = actor->_f_Y() + ymove;
|
t = plane->fA() * dest.X + plane->fB() * dest.Y + plane->fC() * actor->Z() + plane->fD();
|
||||||
t = TMulScale16(plane->a, destx, plane->b, desty, plane->c, actor->_f_Z()) + plane->d;
|
|
||||||
if (t < 0)
|
if (t < 0)
|
||||||
{ // Desired location is behind (below) the plane
|
{ // Desired location is behind (below) the plane
|
||||||
// (i.e. Walking up the plane)
|
// (i.e. Walking up the plane)
|
||||||
|
@ -2968,11 +2965,9 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov
|
||||||
sector_t *sec = node->m_sector;
|
sector_t *sec = node->m_sector;
|
||||||
if (sec->floorplane.c >= STEEPSLOPE)
|
if (sec->floorplane.c >= STEEPSLOPE)
|
||||||
{
|
{
|
||||||
fixedvec3 pos = actor->_f_PosRelative(sec);
|
DVector3 pos = actor->PosRelative(sec) +move;
|
||||||
pos.x += xmove;
|
|
||||||
pos.y += ymove;
|
|
||||||
|
|
||||||
if (sec->floorplane.ZatPointF(pos) >= actor->Z() - actor->MaxStepHeight)
|
if (sec->floorplane.ZatPoint(pos) >= actor->Z() - actor->MaxStepHeight)
|
||||||
{
|
{
|
||||||
dopush = false;
|
dopush = false;
|
||||||
break;
|
break;
|
||||||
|
@ -2982,31 +2977,28 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov
|
||||||
}
|
}
|
||||||
if (dopush)
|
if (dopush)
|
||||||
{
|
{
|
||||||
xmove = plane->a * 2;
|
actor->Vel.X = move.X = plane->fA() * 2;
|
||||||
ymove = plane->b * 2;
|
actor->Vel.Y = move.Y = plane->fB() * 2;
|
||||||
actor->Vel.X = FIXED2DBL(xmove);
|
|
||||||
actor->Vel.Y = FIXED2DBL(ymove);
|
|
||||||
}
|
}
|
||||||
return (actor->floorsector == actor->Sector) ? plane : NULL;
|
return (actor->floorsector == actor->Sector) ? plane : NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Slide the desired location along the plane's normal
|
// Slide the desired location along the plane's normal
|
||||||
// so that it lies on the plane's surface
|
// so that it lies on the plane's surface
|
||||||
destx -= FixedMul(plane->a, t);
|
dest.X -= plane->fA() * t;
|
||||||
desty -= FixedMul(plane->b, t);
|
dest.Y -= plane->fB() * t;
|
||||||
xmove = destx - actor->_f_X();
|
move = dest - actor->Pos().XY();
|
||||||
ymove = desty - actor->_f_Y();
|
|
||||||
return (actor->floorsector == actor->Sector) ? plane : NULL;
|
return (actor->floorsector == actor->Sector) ? plane : NULL;
|
||||||
}
|
}
|
||||||
else if (t > 0)
|
else if (t > 0)
|
||||||
{ // Desired location is in front of (above) the plane
|
{ // Desired location is in front of (above) the plane
|
||||||
if (planezhere == actor->_f_Z())
|
if (fabs(planezhere - actor->Z() < (1/65536.))) // it is very important not to be too precise here.
|
||||||
{ // Actor's current spot is on/in the plane, so walk down it
|
{
|
||||||
|
// Actor's current spot is on/in the plane, so walk down it
|
||||||
// Same principle as walking up, except reversed
|
// Same principle as walking up, except reversed
|
||||||
destx += FixedMul(plane->a, t);
|
dest.X += plane->fA() * t;
|
||||||
desty += FixedMul(plane->b, t);
|
dest.Y += plane->fB() * t;
|
||||||
xmove = destx - actor->_f_X();
|
move = dest - actor->Pos().XY();
|
||||||
ymove = desty - actor->_f_Y();
|
|
||||||
return (actor->floorsector == actor->Sector) ? plane : NULL;
|
return (actor->floorsector == actor->Sector) ? plane : NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
17
src/r_defs.h
17
src/r_defs.h
|
@ -246,6 +246,23 @@ struct secplane_t
|
||||||
|
|
||||||
fixed_t a, b, c, d, ic;
|
fixed_t a, b, c, d, ic;
|
||||||
|
|
||||||
|
double fA() const
|
||||||
|
{
|
||||||
|
return FIXED2FLOAT(a);
|
||||||
|
}
|
||||||
|
double fB() const
|
||||||
|
{
|
||||||
|
return FIXED2FLOAT(b);
|
||||||
|
}
|
||||||
|
double fC() const
|
||||||
|
{
|
||||||
|
return FIXED2FLOAT(c);
|
||||||
|
}
|
||||||
|
double fD() const
|
||||||
|
{
|
||||||
|
return FIXED2FLOAT(d);
|
||||||
|
}
|
||||||
|
|
||||||
bool isSlope() const
|
bool isSlope() const
|
||||||
{
|
{
|
||||||
return a != 0 || b != 0;
|
return a != 0 || b != 0;
|
||||||
|
|
Loading…
Reference in a new issue