major speedup in PM_RecursiveHullCheck

This commit is contained in:
Forest Hale 2000-10-24 10:47:01 +00:00
parent c757f969c4
commit 0040dd25ff

View file

@ -203,6 +203,8 @@ qboolean PM_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec
int side; int side;
float midf; float midf;
// LordHavoc: a goto! everyone flee in terror... :)
loc0:
// check for empty // check for empty
if (num < 0) if (num < 0)
{ {
@ -219,6 +221,7 @@ qboolean PM_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec
return true; // empty return true; // empty
} }
// LordHavoc: this can be eliminated by validating in the loader... but Mercury told me not to bother
if (num < hull->firstclipnode || num > hull->lastclipnode) if (num < hull->firstclipnode || num > hull->lastclipnode)
Sys_Error ("PM_RecursiveHullCheck: bad node number"); Sys_Error ("PM_RecursiveHullCheck: bad node number");
@ -238,50 +241,46 @@ qboolean PM_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec
t1 = DotProduct (plane->normal, p1) - plane->dist; t1 = DotProduct (plane->normal, p1) - plane->dist;
t2 = DotProduct (plane->normal, p2) - plane->dist; t2 = DotProduct (plane->normal, p2) - plane->dist;
} }
#if 1 // LordHavoc: recursion optimization
if (t1 >= 0 && t2 >= 0) if (t1 >= 0 && t2 >= 0)
return PM_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1, p2, trace); // return PM_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1, p2, trace);
{
num = node->children[0];
goto loc0;
}
if (t1 < 0 && t2 < 0) if (t1 < 0 && t2 < 0)
return PM_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1, p2, trace); // return PM_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1, p2, trace);
#else {
if ( (t1 >= DIST_EPSILON && t2 >= DIST_EPSILON) || (t2 > t1 && t1 >= 0) ) num = node->children[1];
return PM_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1, p2, trace); goto loc0;
if ( (t1 <= -DIST_EPSILON && t2 <= -DIST_EPSILON) || (t2 < t1 && t1 <= 0) ) }
return PM_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1, p2, trace);
#endif
// put the crosspoint DIST_EPSILON pixels on the near side // put the crosspoint DIST_EPSILON pixels on the near side
if (t1 < 0) side = (t1 < 0);
frac = (t1 + DIST_EPSILON)/(t1-t2); if (side)
frac = bound(0, (t1 + DIST_EPSILON) / (t1 - t2), 1);
else else
frac = (t1 - DIST_EPSILON)/(t1-t2); frac = bound(0, (t1 - DIST_EPSILON) / (t1 - t2), 1);
if (frac < 0)
frac = 0;
if (frac > 1)
frac = 1;
midf = p1f + (p2f - p1f)*frac; midf = p1f + (p2f - p1f)*frac;
for (i=0 ; i<3 ; i++) for (i=0 ; i<3 ; i++)
mid[i] = p1[i] + frac*(p2[i] - p1[i]); mid[i] = p1[i] + frac*(p2[i] - p1[i]);
side = (t1 < 0);
// move up to the node // move up to the node
if (!PM_RecursiveHullCheck (hull, node->children[side], p1f, midf, p1, mid, trace) ) if (!PM_RecursiveHullCheck (hull, node->children[side], p1f, midf, p1, mid, trace) )
return false; return false;
#ifdef PARANOID #ifdef PARANOID
if (PM_HullPointContents (pm_hullmodel, mid, node->children[side]) if (PM_HullPointContents (pm_hullmodel, mid, node->children[side]) == CONTENTS_SOLID)
== CONTENTS_SOLID)
{ {
Con_Printf ("mid PointInHullSolid\n"); Con_Printf ("mid PointInHullSolid\n");
return false; return false;
} }
#endif #endif
if (PM_HullPointContents (hull, node->children[side^1], mid) // LordHavoc: warning to the clumsy, this recursion can not be optimized because mid would need to be duplicated on a stack
!= CONTENTS_SOLID) if (PM_HullPointContents (hull, node->children[side^1], mid) != CONTENTS_SOLID)
// go past the node // go past the node
return PM_RecursiveHullCheck (hull, node->children[side^1], midf, p2f, mid, p2, trace); return PM_RecursiveHullCheck (hull, node->children[side^1], midf, p2f, mid, p2, trace);
@ -298,12 +297,15 @@ qboolean PM_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec
} }
else else
{ {
VectorSubtract (vec3_origin, plane->normal, trace->plane.normal); // LordHavoc: vec3_origin is evil; the compiler can not rely on it being '0 0 0'
// VectorSubtract (vec3_origin, plane->normal, trace->plane.normal);
trace->plane.normal[0] = -plane->normal[0];
trace->plane.normal[1] = -plane->normal[1];
trace->plane.normal[2] = -plane->normal[2];
trace->plane.dist = -plane->dist; trace->plane.dist = -plane->dist;
} }
while (PM_HullPointContents (hull, hull->firstclipnode, mid) while (PM_HullPointContents (hull, hull->firstclipnode, mid) == CONTENTS_SOLID)
== CONTENTS_SOLID)
{ // shouldn't really happen, but does occasionally { // shouldn't really happen, but does occasionally
frac -= 0.1; frac -= 0.1;
if (frac < 0) if (frac < 0)