mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Sight check improvements
- Divline crossed check is its own function. - Remove the weird P_InterceptVector duplicate, so we can take advantage of the precise version from the earlier commit - P_CrossBSPNode uses R_PointOnSide instead of P_DivlineSide; this function is more optimized and designed for BSP traversal. Some of these are additionally also from DSDA-Doom / PrBoom+ / LxDoom
This commit is contained in:
parent
5022e2090b
commit
96037f17d3
1 changed files with 34 additions and 72 deletions
106
src/p_sight.c
106
src/p_sight.c
|
|
@ -59,66 +59,22 @@ static INT32 sightcounts[2];
|
|||
//
|
||||
// Returns side 0 (front), 1 (back), or 2 (on).
|
||||
//
|
||||
static INT32 P_DivlineSide(fixed_t x, fixed_t y, divline_t *node)
|
||||
// killough 4/19/98: made static, cleaned up
|
||||
|
||||
static INT32 P_DivlineSide(fixed_t x, fixed_t y, const divline_t *node)
|
||||
{
|
||||
fixed_t dx, dy, left, right;
|
||||
|
||||
if (!node->dx)
|
||||
{
|
||||
if (x == node->x)
|
||||
return 2;
|
||||
|
||||
if (x <= node->x)
|
||||
return (node->dy > 0);
|
||||
|
||||
return (node->dy < 0);
|
||||
}
|
||||
|
||||
if (!node->dy)
|
||||
{
|
||||
if (y == node->y)
|
||||
return 2;
|
||||
|
||||
if (y <= node->y)
|
||||
return (node->dx < 0);
|
||||
|
||||
return (node->dx > 0);
|
||||
}
|
||||
|
||||
dx = x - node->x;
|
||||
dy = y - node->y;
|
||||
|
||||
left = (node->dy>>FRACBITS) * (dx>>FRACBITS);
|
||||
right = (dy>>FRACBITS) * (node->dx>>FRACBITS);
|
||||
|
||||
if (right < left)
|
||||
return 0; // front side
|
||||
|
||||
if (left == right)
|
||||
return 2;
|
||||
|
||||
return 1; // back side
|
||||
fixed_t left, right;
|
||||
return
|
||||
!node->dx ? x == node->x ? 2 : x <= node->x ? node->dy > 0 : node->dy < 0 :
|
||||
!node->dy ? y == node->y ? 2 : y <= node->y ? node->dx < 0 : node->dx > 0 :
|
||||
(right = ((y - node->y) >> FRACBITS) * (node->dx >> FRACBITS)) <
|
||||
(left = ((x - node->x) >> FRACBITS) * (node->dy >> FRACBITS)) ? 0 :
|
||||
right == left ? 2 : 1;
|
||||
}
|
||||
|
||||
//
|
||||
// P_InterceptVector2
|
||||
//
|
||||
// Returns the fractional intercept point along the first divline.
|
||||
// This is only called by the addthings and addlines traversers.
|
||||
//
|
||||
static fixed_t P_InterceptVector2(divline_t *v2, divline_t *v1)
|
||||
static INT32 P_DivlineCrossed(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, const divline_t *node)
|
||||
{
|
||||
fixed_t frac, num, den;
|
||||
|
||||
den = FixedMul(v1->dy>>8, v2->dx) - FixedMul(v1->dx>>8, v2->dy);
|
||||
|
||||
if (!den)
|
||||
return 0;
|
||||
|
||||
num = FixedMul((v1->x - v2->x)>>8, v1->dy) + FixedMul((v2->y - v1->y)>>8, v1->dx);
|
||||
frac = FixedDiv(num, den);
|
||||
|
||||
return frac;
|
||||
return (P_DivlineSide(x1, y1, node) == P_DivlineSide(x2, y2, node));
|
||||
}
|
||||
|
||||
static boolean P_IsVisiblePolyObj(polyobj_t *po, divline_t *divl, register los_t *los)
|
||||
|
|
@ -140,7 +96,7 @@ static boolean P_IsVisiblePolyObj(polyobj_t *po, divline_t *divl, register los_t
|
|||
}
|
||||
*/
|
||||
|
||||
frac = P_InterceptVector2(&los->strace, divl);
|
||||
frac = P_InterceptVector(&los->strace, divl);
|
||||
|
||||
// get slopes of top and bottom of this polyobject line
|
||||
topslope = FixedDiv(polysec->ceilingheight - los->sightzstart , frac);
|
||||
|
|
@ -191,16 +147,14 @@ static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los, register
|
|||
v2 = line->v2;
|
||||
|
||||
// line isn't crossed?
|
||||
if (P_DivlineSide(v1->x, v1->y, &los->strace) ==
|
||||
P_DivlineSide(v2->x, v2->y, &los->strace))
|
||||
if (P_DivlineCrossed(v1->x, v1->y, v2->x, v2->y, &los->strace))
|
||||
continue;
|
||||
|
||||
divl.dx = v2->x - (divl.x = v1->x);
|
||||
divl.dy = v2->y - (divl.y = v1->y);
|
||||
|
||||
// line isn't crossed?
|
||||
if (P_DivlineSide(los->strace.x, los->strace.y, &divl) ==
|
||||
P_DivlineSide(los->t2x, los->t2y, &divl))
|
||||
if (P_DivlineCrossed(los->strace.x, los->strace.y, los->t2x, los->t2y, &divl))
|
||||
continue;
|
||||
|
||||
if (funcs->validatePolyobj(po, &divl, los) == false)
|
||||
|
|
@ -228,7 +182,7 @@ static boolean P_IsVisible(seg_t *seg, divline_t *divl, register los_t *los)
|
|||
}
|
||||
|
||||
// calculate fractional intercept (how far along we are divided by how far we are from t2)
|
||||
frac = P_InterceptVector2(&los->strace, divl);
|
||||
frac = P_InterceptVector(&los->strace, divl);
|
||||
|
||||
front = seg->frontsector;
|
||||
back = seg->backsector;
|
||||
|
|
@ -377,7 +331,7 @@ static boolean P_CanBotTraverse(seg_t *seg, divline_t *divl, register los_t *los
|
|||
}
|
||||
|
||||
// calculate fractional intercept (how far along we are divided by how far we are from t2)
|
||||
frac = P_InterceptVector2(&los->strace, divl);
|
||||
frac = P_InterceptVector(&los->strace, divl);
|
||||
|
||||
// calculate position at intercept
|
||||
g_tm.x = los->strace.x + FixedMul(los->strace.dx, frac);
|
||||
|
|
@ -445,7 +399,7 @@ static boolean P_CanWaypointTraverse(seg_t *seg, divline_t *divl, register los_t
|
|||
}
|
||||
|
||||
// calculate fractional intercept (how far along we are divided by how far we are from t2)
|
||||
frac = P_InterceptVector2(&los->strace, divl);
|
||||
frac = P_InterceptVector(&los->strace, divl);
|
||||
|
||||
// calculate position at intercept
|
||||
g_tm.x = los->strace.x + FixedMul(los->strace.dx, frac);
|
||||
|
|
@ -569,16 +523,14 @@ static boolean P_CrossSubsector(size_t num, register los_t *los, register los_fu
|
|||
v2 = line->v2;
|
||||
|
||||
// line isn't crossed?
|
||||
if (P_DivlineSide(v1->x, v1->y, &los->strace) ==
|
||||
P_DivlineSide(v2->x, v2->y, &los->strace))
|
||||
if (P_DivlineCrossed(v1->x, v1->y, v2->x, v2->y, &los->strace))
|
||||
continue;
|
||||
|
||||
divl.dx = v2->x - (divl.x = v1->x);
|
||||
divl.dy = v2->y - (divl.y = v1->y);
|
||||
|
||||
// line isn't crossed?
|
||||
if (P_DivlineSide(los->strace.x, los->strace.y, &divl) ==
|
||||
P_DivlineSide(los->t2x, los->t2y, &divl))
|
||||
if (P_DivlineCrossed(los->strace.x, los->strace.y, los->t2x, los->t2y, &divl))
|
||||
continue;
|
||||
|
||||
if (funcs->validate(seg, &divl, los) == false)
|
||||
|
|
@ -597,24 +549,34 @@ static boolean P_CrossSubsector(size_t num, register los_t *los, register los_fu
|
|||
// if strace crosses the given node successfully.
|
||||
//
|
||||
// killough 4/20/98: rewritten to remove tail recursion, clean up, and optimize
|
||||
// cph - Made to use R_PointOnSide instead of P_DivlineSide, since the latter
|
||||
// could return 2 which was ambigous, and the former is
|
||||
// better optimised; also removes two casts :-)
|
||||
|
||||
static boolean P_CrossBSPNode(INT32 bspnum, register los_t *los, register los_funcs_t *funcs)
|
||||
{
|
||||
while (!(bspnum & NF_SUBSECTOR))
|
||||
{
|
||||
register node_t *bsp = nodes + bspnum;
|
||||
INT32 side = P_DivlineSide(los->strace.x, los->strace.y, (divline_t *)bsp) & 1;
|
||||
INT32 side = R_PointOnSide(los->strace.x, los->strace.y, bsp);
|
||||
INT32 side2 = R_PointOnSide(los->t2x, los->t2y, bsp);
|
||||
|
||||
if (side == P_DivlineSide(los->t2x, los->t2y, (divline_t *) bsp))
|
||||
if (side == side2)
|
||||
{
|
||||
bspnum = bsp->children[side]; // doesn't touch the other side
|
||||
// doesn't touch the other side
|
||||
bspnum = bsp->children[side];
|
||||
}
|
||||
else // the partition plane is crossed here
|
||||
else
|
||||
{
|
||||
// the partition plane is crossed here
|
||||
if (!P_CrossBSPNode(bsp->children[side], los, funcs))
|
||||
{
|
||||
return false; // cross the starting side
|
||||
}
|
||||
else
|
||||
{
|
||||
bspnum = bsp->children[side ^ 1]; // cross the ending side
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue