mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 06:51:47 +00:00
partially reworked PM_RecursiveHullCheck on the path to non-recursive.
Doesn't seem to be any slower than the old version (still there for now, but not used) and might even be slightly faster already even though there's not difference in call counts. Committing this now so I don't lose my work (mostly to me getting frustrated and killing it:)
This commit is contained in:
parent
79689baa83
commit
825e1f88fd
1 changed files with 117 additions and 17 deletions
|
@ -104,7 +104,7 @@ PM_HullForBox (const vec3_t mins, const vec3_t maxs)
|
|||
return &box_hull;
|
||||
}
|
||||
|
||||
int
|
||||
inline int
|
||||
PM_HullPointContents (hull_t *hull, int num, const vec3_t p)
|
||||
{
|
||||
dclipnode_t *node;
|
||||
|
@ -162,7 +162,122 @@ PM_PointContents (const vec3_t p)
|
|||
|
||||
// 1/32 epsilon to keep floating point happy
|
||||
#define DIST_EPSILON (0.03125)
|
||||
#if 1
|
||||
static inline void
|
||||
visit_leaf (int num, pmtrace_t *trace)
|
||||
{
|
||||
if (num != CONTENTS_SOLID) {
|
||||
trace->allsolid = false;
|
||||
if (num == CONTENTS_EMPTY)
|
||||
trace->inopen = true;
|
||||
else
|
||||
trace->inwater = true;
|
||||
} else
|
||||
trace->startsolid = true;
|
||||
}
|
||||
|
||||
static inline void
|
||||
fill_trace (hull_t *hull, int num, int side,
|
||||
const vec3_t p1, const vec3_t p2, float p1f, float p2f,
|
||||
float t1, float t2, pmtrace_t *trace)
|
||||
{
|
||||
mplane_t *plane;
|
||||
float frac;
|
||||
int i;
|
||||
|
||||
// the other side of the node is solid, this is the impact point
|
||||
// put the crosspoint DIST_EPSILON pixels on the near side to guarantee
|
||||
// mid is on the correct side of the plane
|
||||
plane = hull->planes + hull->clipnodes[num].planenum;
|
||||
if (!side) {
|
||||
VectorCopy (plane->normal, trace->plane.normal);
|
||||
trace->plane.dist = plane->dist;
|
||||
frac = (t1 - DIST_EPSILON) / (t1 - t2);
|
||||
} else {
|
||||
VectorSubtract (vec3_origin, plane->normal, trace->plane.normal);
|
||||
trace->plane.dist = -plane->dist;
|
||||
frac = (t1 + DIST_EPSILON) / (t1 - t2);
|
||||
}
|
||||
|
||||
frac = bound (0, frac, 1);
|
||||
|
||||
trace->fraction = p1f + (p2f - p1f) * frac;
|
||||
for (i = 0; i < 3; i++)
|
||||
trace->endpos[i] = p1[i] + frac * (p2[i] - p1[i]);
|
||||
}
|
||||
|
||||
static inline float
|
||||
calc_mid (float t1, float t2, const vec3_t p1, const vec3_t p2,
|
||||
float p1f, float p2f, vec3_t mid)
|
||||
{
|
||||
float frac = t1 / (t1 - t2);
|
||||
int i;
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
mid[i] = p1[i] + frac*(p2[i] - p1[i]);
|
||||
return p1f + (p2f - p1f)*frac;
|
||||
}
|
||||
|
||||
static inline void
|
||||
calc_dists (const mplane_t *plane, const vec3_t p1, const vec3_t p2,
|
||||
float *t1, float *t2)
|
||||
{
|
||||
if (plane->type < 3) {
|
||||
*t1 = p1[plane->type] - plane->dist;
|
||||
*t2 = p2[plane->type] - plane->dist;
|
||||
} else {
|
||||
*t1 = DotProduct (plane->normal, p1) - plane->dist;
|
||||
*t2 = DotProduct (plane->normal, p2) - plane->dist;
|
||||
}
|
||||
}
|
||||
|
||||
qboolean
|
||||
PM_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f,
|
||||
const vec3_t p1, const vec3_t p2, pmtrace_t *trace)
|
||||
{
|
||||
int front, back;
|
||||
dclipnode_t *node;
|
||||
float t1, t2, midf;
|
||||
int side;
|
||||
vec3_t mid;
|
||||
vec3_t _p1;
|
||||
|
||||
while (1) {
|
||||
while (num >= 0) {
|
||||
node = hull->clipnodes + num;
|
||||
calc_dists (hull->planes + node->planenum, p1, p2, &t1, &t2);
|
||||
|
||||
side = (t1 < 0);
|
||||
if (t1 >= 0 != t2 >= 0)
|
||||
break;
|
||||
num = node->children[side];
|
||||
}
|
||||
if (num < 0) {
|
||||
visit_leaf (num, trace);
|
||||
return true;
|
||||
}
|
||||
|
||||
midf = calc_mid (t1, t2, p1, p2, p1f, p2f, mid);
|
||||
|
||||
front = node->children[side];
|
||||
if (!PM_RecursiveHullCheck (hull, front, p1f, midf, p1, mid, trace))
|
||||
return false;
|
||||
|
||||
back = node->children[side ^ 1];
|
||||
if (PM_HullPointContents (hull, back, mid) == CONTENTS_SOLID) {
|
||||
// got out of the solid area?
|
||||
if (!trace->allsolid)
|
||||
fill_trace (hull, num, side, p1, p2, p1f, p2f,
|
||||
t1, t2, trace);
|
||||
return false;
|
||||
}
|
||||
num = back;
|
||||
VectorCopy (mid, _p1);
|
||||
p1f = midf;
|
||||
p1 = _p1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
qboolean
|
||||
PM_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f,
|
||||
const vec3_t p1, const vec3_t p2, pmtrace_t *trace)
|
||||
|
@ -243,22 +358,6 @@ PM_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f,
|
|||
trace->plane.dist = -plane->dist;
|
||||
}
|
||||
|
||||
#if 0 //XXX I don't think this is needed any more, but leave it in for now
|
||||
while (PM_HullPointContents (hull, hull->firstclipnode, mid)
|
||||
== CONTENTS_SOLID) {
|
||||
// shouldn't really happen, but does occasionally
|
||||
frac -= 0.1;
|
||||
if (frac < 0) {
|
||||
trace->fraction = midf;
|
||||
VectorCopy (mid, trace->endpos);
|
||||
Con_DPrintf ("backup past 0\n");
|
||||
return false;
|
||||
}
|
||||
midf = p1f + (p2f - p1f) * frac;
|
||||
for (i = 0; i < 3; i++)
|
||||
mid[i] = p1[i] + frac * (p2[i] - p1[i]);
|
||||
}
|
||||
#endif
|
||||
// put the crosspoint DIST_EPSILON pixels on the near side to guarantee
|
||||
// mid is on the correct side of the plane
|
||||
if (side)
|
||||
|
@ -276,6 +375,7 @@ PM_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f,
|
|||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
PM_TestPlayerPosition
|
||||
|
|
Loading…
Reference in a new issue