[PATCH] qbsp: implement sloping cuts for DivideNodeBounds

Signed-off-by: Tyrann <tyrann@disenchant.net>
This commit is contained in:
Tyrann 2007-08-19 20:17:23 +09:30
parent 0b70607015
commit 6add073624
2 changed files with 82 additions and 11 deletions

View File

@ -196,6 +196,19 @@ vec_t VectorNormalize(vec3_t v);
void VectorInverse(vec3_t v);
void VectorScale(const vec3_t v, const vec_t scale, vec3_t out);
#define min(a,b) ({ \
typeof(a) a_ = (a); \
typeof(b) b_ = (b); \
(void)(&a_ == &b_); \
(a_ < b_) ? a_ : b_; \
})
#define max(a,b) ({ \
typeof(a) a_ = (a); \
typeof(b) b_ = (b); \
(void)(&a_ == &b_); \
(a_ > b_) ? a_ : b_; \
})
//====== bspfile.h

View File

@ -86,6 +86,72 @@ FaceSide(face_t *in, plane_t *split)
return SIDE_ON;
}
/*
* Split a bounding box by a plane; The front and back bounds returned
* are such that they completely contain the portion of the input box
* on that side of the plane. Therefore, if the split plane is
* non-axial, then the returned bounds will overlap.
*/
static void
DivideBounds(const vec3_t mins, const vec3_t maxs, const plane_t *split,
vec3_t front_mins, vec3_t front_maxs,
vec3_t back_mins, vec3_t back_maxs)
{
int a, b, c, i, j;
vec_t dist1, dist2, mid, split_mins, split_maxs;
vec3_t corner;
const vec_t *bounds[] = { mins, maxs };
VectorCopy(mins, front_mins);
VectorCopy(mins, back_mins);
VectorCopy(maxs, front_maxs);
VectorCopy(maxs, back_maxs);
if (split->type < 3) {
front_mins[split->type] = back_maxs[split->type] = split->dist;
return;
}
/* Make proper sloping cuts... */
for (a = 0; a < 3; ++a) {
/* Check for parallel case... no intersection */
if (fabs(split->normal[a]) < NORMAL_EPSILON)
continue;
b = (a + 1) % 3;
c = (a + 2) % 3;
split_mins = maxs[a];
split_maxs = mins[a];
for (i = 0; i < 2; ++i) {
corner[b] = bounds[i][b];
for (j = 0; j < 2; ++j) {
corner[c] = bounds[j][c];
corner[a] = bounds[0][a];
dist1 = DotProduct(corner, split->normal) - split->dist;
corner[a] = bounds[1][a];
dist2 = DotProduct(corner, split->normal) - split->dist;
mid = bounds[1][a] - bounds[0][a];
mid *= (dist1 / (dist1 - dist2));
mid += bounds[0][a];
split_mins = max(min(mid, split_mins), mins[a]);
split_maxs = min(max(mid, split_maxs), maxs[a]);
}
}
if (split->normal[a] > 0) {
front_mins[a] = split_mins;
back_maxs[a] = split_maxs;
} else {
back_mins[a] = split_mins;
front_maxs[a] = split_maxs;
}
}
}
/*
==================
ChooseMidPlaneFromList
@ -426,17 +492,9 @@ DivideNodeBounds
static void
DivideNodeBounds(node_t *node, plane_t *split)
{
VectorCopy(node->mins, node->children[0]->mins);
VectorCopy(node->mins, node->children[1]->mins);
VectorCopy(node->maxs, node->children[0]->maxs);
VectorCopy(node->maxs, node->children[1]->maxs);
// OPTIMIZE: sloping cuts can give a better bbox than this...
if (split->type > 2)
return;
node->children[0]->mins[split->type] =
node->children[1]->maxs[split->type] = split->dist;
DivideBounds(node->mins, node->maxs, split,
node->children[0]->mins, node->children[0]->maxs,
node->children[1]->mins, node->children[1]->maxs);
}
/*