Merge branch 'better_papercollision' into 'master'

Better papercollision

Diagonal bounding boxes are no longer root 2 larger than they should be. Testwad is <root>/toaster/sawb.wad. Nice and simple.

See merge request !49
This commit is contained in:
Monster Iestyn 2017-01-25 17:34:43 -05:00
commit cfb5a9d904
1 changed files with 25 additions and 19 deletions

View File

@ -523,23 +523,27 @@ static boolean PIT_CheckThing(mobj_t *thing)
junk.v1 = &v1; junk.v1 = &v1;
junk.v2 = &v2; junk.v2 = &v2;
junk.dx = v2.x - v1.x; junk.dx = 2*cosradius; // v2.x - v1.x;
junk.dy = v2.y - v1.y; junk.dy = 2*sinradius; // v2.y - v1.y;
if (tmthing->flags & MF_PAPERCOLLISION) // more strenuous checking to prevent clipping issues if (tmthing->flags & MF_PAPERCOLLISION) // more strenuous checking to prevent clipping issues
{ {
INT32 check1, check2, check3, check4; INT32 check1, check2, check3, check4;
cosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT)); fixed_t tmcosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT));
sinradius = FixedMul(tmthing->radius, FINESINE(tmthing->angle>>ANGLETOFINESHIFT)); fixed_t tmsinradius = FixedMul(tmthing->radius, FINESINE(tmthing->angle>>ANGLETOFINESHIFT));
check1 = P_PointOnLineSide(tmx - cosradius, tmy - sinradius, &junk); if (abs(thing->x - tmx) >= (abs(tmcosradius) + abs(cosradius)) || abs(thing->y - tmy) >= (abs(tmsinradius) + abs(sinradius)))
check2 = P_PointOnLineSide(tmx + cosradius, tmy + sinradius, &junk); return true; // didn't hit it
check3 = P_PointOnLineSide(tmx + tmthing->momx - cosradius, tmy + tmthing->momy - sinradius, &junk); check1 = P_PointOnLineSide(tmx - tmcosradius, tmy - tmsinradius, &junk);
check4 = P_PointOnLineSide(tmx + tmthing->momx + cosradius, tmy + tmthing->momy + sinradius, &junk); check2 = P_PointOnLineSide(tmx + tmcosradius, tmy + tmsinradius, &junk);
check3 = P_PointOnLineSide(tmx + tmthing->momx - tmcosradius, tmy + tmthing->momy - tmsinradius, &junk);
check4 = P_PointOnLineSide(tmx + tmthing->momx + tmcosradius, tmy + tmthing->momy + tmsinradius, &junk);
if ((check1 == check2) && (check2 == check3) && (check3 == check4)) if ((check1 == check2) && (check2 == check3) && (check3 == check4))
return true; // the line doesn't cross between collider's start or end return true; // the line doesn't cross between collider's start or end
} }
else else
{ {
if (abs(thing->x - tmx) >= (tmthing->radius + abs(cosradius)) || abs(thing->y - tmy) >= (tmthing->radius + abs(sinradius)))
return true; // didn't hit it
if ((P_PointOnLineSide(tmx - tmthing->radius, tmy - tmthing->radius, &junk) if ((P_PointOnLineSide(tmx - tmthing->radius, tmy - tmthing->radius, &junk)
== P_PointOnLineSide(tmx + tmthing->radius, tmy + tmthing->radius, &junk)) == P_PointOnLineSide(tmx + tmthing->radius, tmy + tmthing->radius, &junk))
&& (P_PointOnLineSide(tmx + tmthing->radius, tmy - tmthing->radius, &junk) && (P_PointOnLineSide(tmx + tmthing->radius, tmy - tmthing->radius, &junk)
@ -549,25 +553,27 @@ static boolean PIT_CheckThing(mobj_t *thing)
} }
else if (tmthing->flags & MF_PAPERCOLLISION) else if (tmthing->flags & MF_PAPERCOLLISION)
{ {
fixed_t cosradius, sinradius; fixed_t tmcosradius, tmsinradius;
vertex_t v1, v2; // fake vertexes vertex_t v1, v2; // fake vertexes
line_t junk; // fake linedef line_t junk; // fake linedef
cosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT)); tmcosradius = FixedMul(tmthing->radius, FINECOSINE(tmthing->angle>>ANGLETOFINESHIFT));
sinradius = FixedMul(tmthing->radius, FINESINE(tmthing->angle>>ANGLETOFINESHIFT)); tmsinradius = FixedMul(tmthing->radius, FINESINE(tmthing->angle>>ANGLETOFINESHIFT));
v1.x = tmx - cosradius; if (abs(thing->x - tmx) >= (thing->radius + abs(tmcosradius)) || abs(thing->y - tmy) >= (thing->radius + abs(tmsinradius)))
v1.y = tmy - sinradius; return true; // didn't hit it
v2.x = tmx + cosradius;
v2.y = tmy + sinradius; v1.x = tmx - tmcosradius;
v1.y = tmy - tmsinradius;
v2.x = tmx + tmcosradius;
v2.y = tmy + tmsinradius;
junk.v1 = &v1; junk.v1 = &v1;
junk.v2 = &v2; junk.v2 = &v2;
junk.dx = v2.x - v1.x; junk.dx = 2*tmcosradius; // v2.x - v1.x;
junk.dy = v2.y - v1.y; junk.dy = 2*tmsinradius; // v2.y - v1.y;
// no need to check whether thing has MF_PAPERCOLLISION, since checked above
// no need to check whether other thing has MF_PAPERCOLLISION, since would fall under other condition
if ((P_PointOnLineSide(thing->x - thing->radius, thing->y - thing->radius, &junk) if ((P_PointOnLineSide(thing->x - thing->radius, thing->y - thing->radius, &junk)
== P_PointOnLineSide(thing->x + thing->radius, thing->y + thing->radius, &junk)) == P_PointOnLineSide(thing->x + thing->radius, thing->y + thing->radius, &junk))
&& (P_PointOnLineSide(thing->x + thing->radius, thing->y - thing->radius, &junk) && (P_PointOnLineSide(thing->x + thing->radius, thing->y - thing->radius, &junk)