qbsp: factor out leafnode intersection from LineIntersect_r

Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
This commit is contained in:
Kevin Shanahan 2013-04-24 07:01:37 +09:30
parent 4543817f59
commit 1e39a7e614
1 changed files with 69 additions and 63 deletions

View File

@ -226,82 +226,88 @@ of the faces in the node, false if it does.
================= =================
*/ */
static bool static bool
LineIntersect_r(const node_t *node, const vec3_t point1, const vec3_t point2) LineIntersect_Leafnode(const node_t *node,
const vec3_t point1, const vec3_t point2)
{ {
// Process this node's faces if leaf node face_t *const *markfaces;
if (node->contents) { const face_t *face;
face_t *const *markfaces;
const face_t *face;
vec_t dist1, dist2;
vec3_t dir;
vec3_t mid, mins, maxs;
int i, j;
for (markfaces = node->markfaces; *markfaces; markfaces++) { for (markfaces = node->markfaces; *markfaces; markfaces++) {
for (face = *markfaces; face; face = face->original) { for (face = *markfaces; face; face = face->original) {
const plane_t *plane = &map.planes[face->planenum]; const plane_t *const plane = &map.planes[face->planenum];
dist1 = DotProduct(point1, plane->normal) - plane->dist; const vec_t dist1 = DotProduct(point1, plane->normal) - plane->dist;
dist2 = DotProduct(point2, plane->normal) - plane->dist; const vec_t dist2 = DotProduct(point2, plane->normal) - plane->dist;
vec3_t mid, mins, maxs;
int i, j;
// Line segment doesn't cross the plane // Line segment doesn't cross the plane
if (dist1 < -ON_EPSILON && dist2 < -ON_EPSILON) if (dist1 < -ON_EPSILON && dist2 < -ON_EPSILON)
continue; continue;
if (dist1 > ON_EPSILON && dist2 > ON_EPSILON) if (dist1 > ON_EPSILON && dist2 > ON_EPSILON)
continue; continue;
if (fabs(dist1) < ON_EPSILON) { if (fabs(dist1) < ON_EPSILON) {
if (fabs(dist2) < ON_EPSILON) if (fabs(dist2) < ON_EPSILON)
return false; /* too short/close */ return false; /* too short/close */
VectorCopy(point1, mid); VectorCopy(point1, mid);
} else if (fabs(dist2) < ON_EPSILON) { } else if (fabs(dist2) < ON_EPSILON) {
VectorCopy(point2, mid); VectorCopy(point2, mid);
} else { } else {
// Find the midpoint on the plane of the face /* Find the midpoint on the plane of the face */
VectorSubtract(point2, point1, dir); vec3_t pointvec;
VectorMA(point1, dist1 / (dist1 - dist2), dir, mid); VectorSubtract(point2, point1, pointvec);
VectorMA(point1, dist1 / (dist1 - dist2), pointvec, mid);
}
// Do test here for point in polygon (face)
// Quick hack
mins[0] = mins[1] = mins[2] = VECT_MAX;
maxs[0] = maxs[1] = maxs[2] = -VECT_MAX;
for (i = 0; i < face->w.numpoints; i++)
for (j = 0; j < 3; j++) {
if (face->w.points[i][j] < mins[j])
mins[j] = face->w.points[i][j];
if (face->w.points[i][j] > maxs[j])
maxs[j] = face->w.points[i][j];
} }
// Do test here for point in polygon (face) if (mid[0] < mins[0] - ON_EPSILON ||
// Quick hack mid[1] < mins[1] - ON_EPSILON ||
mins[0] = mins[1] = mins[2] = VECT_MAX; mid[2] < mins[2] - ON_EPSILON ||
maxs[0] = maxs[1] = maxs[2] = -VECT_MAX; mid[0] > maxs[0] + ON_EPSILON ||
for (i = 0; i < face->w.numpoints; i++) mid[1] > maxs[1] + ON_EPSILON ||
for (j = 0; j < 3; j++) { mid[2] > maxs[2] + ON_EPSILON)
if (face->w.points[i][j] < mins[j]) continue;
mins[j] = face->w.points[i][j];
if (face->w.points[i][j] > maxs[j])
maxs[j] = face->w.points[i][j];
}
if (mid[0] < mins[0] - ON_EPSILON || return false;
mid[1] < mins[1] - ON_EPSILON ||
mid[2] < mins[2] - ON_EPSILON ||
mid[0] > maxs[0] + ON_EPSILON ||
mid[1] > maxs[1] + ON_EPSILON ||
mid[2] > maxs[2] + ON_EPSILON)
continue;
return false;
}
} }
} else {
const plane_t *plane = &map.planes[node->planenum];
const vec_t dist1 = DotProduct(point1, plane->normal) - plane->dist;
const vec_t dist2 = DotProduct(point2, plane->normal) - plane->dist;
if (dist1 < -ON_EPSILON && dist2 < -ON_EPSILON)
return LineIntersect_r(node->children[1], point1, point2);
if (dist1 > ON_EPSILON && dist2 > ON_EPSILON)
return LineIntersect_r(node->children[0], point1, point2);
if (!LineIntersect_r(node->children[0], point1, point2))
return false;
if (!LineIntersect_r(node->children[1], point1, point2))
return false;
} }
return true; return true;
} }
static bool
LineIntersect_r(const node_t *node, const vec3_t point1, const vec3_t point2)
{
if (node->contents)
return LineIntersect_Leafnode(node, point1, point2);
const plane_t *const plane = &map.planes[node->planenum];
const vec_t dist1 = DotProduct(point1, plane->normal) - plane->dist;
const vec_t dist2 = DotProduct(point2, plane->normal) - plane->dist;
if (dist1 < -ON_EPSILON && dist2 < -ON_EPSILON)
return LineIntersect_r(node->children[1], point1, point2);
if (dist1 > ON_EPSILON && dist2 > ON_EPSILON)
return LineIntersect_r(node->children[0], point1, point2);
if (!LineIntersect_r(node->children[0], point1, point2))
return false;
if (!LineIntersect_r(node->children[1], point1, point2))
return false;
return true;
}
/* /*
================= =================