- 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:
Christoph Oelckers 2016-03-27 14:07:35 +02:00
parent 26ff2f73d7
commit 23d311dd04
3 changed files with 55 additions and 44 deletions

View file

@ -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;
} }

View file

@ -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,18 +2888,17 @@ 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();
@ -2910,14 +2909,13 @@ 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();
@ -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;
} }
} }

View file

@ -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;