qbsp: separate the bsp split plane selection into two passes
All non-detail surfaces are considered and used before any detail surfaces. Signed-off-by: Kevin Shanahan <kmshanah@disenchant.net>
This commit is contained in:
parent
5275c24393
commit
5abd0e369c
|
|
@ -296,53 +296,70 @@ ChoosePlaneFromList(surface_t *surfaces, vec3_t mins, vec3_t maxs)
|
|||
plane_t *plane, *plane2;
|
||||
vec_t distribution, bestdistribution;
|
||||
face_t *face;
|
||||
int pass;
|
||||
|
||||
/* pick the plane that splits the least */
|
||||
minsplits = INT_MAX;
|
||||
bestdistribution = VECT_MAX;
|
||||
bestsurface = NULL;
|
||||
|
||||
for (surf = surfaces; surf; surf = surf->next) {
|
||||
if (surf->onnode)
|
||||
continue;
|
||||
|
||||
plane = &map.planes[surf->planenum];
|
||||
splits = 0;
|
||||
|
||||
for (surf2 = surfaces; surf2; surf2 = surf2->next) {
|
||||
if (surf2 == surf || surf2->onnode)
|
||||
/* Two passes - exhaust all non-detail faces before details */
|
||||
for (pass = 0; pass < 2; pass++) {
|
||||
for (surf = surfaces; surf; surf = surf->next) {
|
||||
if (surf->onnode)
|
||||
continue;
|
||||
plane2 = &map.planes[surf2->planenum];
|
||||
if (plane->type < 3 && plane->type == plane2->type)
|
||||
|
||||
for (face = surf->faces; face; face = face->next) {
|
||||
if (pass && (face->cflags[1] & CFLAGS_DETAIL))
|
||||
break;
|
||||
if (!pass && !(face->cflags[1] & CFLAGS_DETAIL))
|
||||
break;
|
||||
}
|
||||
if (!face)
|
||||
continue;
|
||||
for (face = surf2->faces; face; face = face->next) {
|
||||
if (FaceSide(face, plane) == SIDE_ON) {
|
||||
splits++;
|
||||
if (splits >= minsplits)
|
||||
break;
|
||||
|
||||
plane = &map.planes[surf->planenum];
|
||||
splits = 0;
|
||||
|
||||
for (surf2 = surfaces; surf2; surf2 = surf2->next) {
|
||||
if (surf2 == surf || surf2->onnode)
|
||||
continue;
|
||||
plane2 = &map.planes[surf2->planenum];
|
||||
if (plane->type < 3 && plane->type == plane2->type)
|
||||
continue;
|
||||
for (face = surf2->faces; face; face = face->next) {
|
||||
if (FaceSide(face, plane) == SIDE_ON) {
|
||||
splits++;
|
||||
if (splits >= minsplits)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (splits > minsplits)
|
||||
break;
|
||||
}
|
||||
if (splits > minsplits)
|
||||
break;
|
||||
}
|
||||
if (splits > minsplits)
|
||||
continue;
|
||||
continue;
|
||||
|
||||
/*
|
||||
* if equal numbers axial planes win, otherwise decide on spatial
|
||||
* subdivision
|
||||
*/
|
||||
if (splits < minsplits || (splits == minsplits && plane->type < 3)) {
|
||||
if (plane->type < 3) {
|
||||
distribution = SplitPlaneMetric(plane, mins, maxs);
|
||||
if (distribution > bestdistribution && splits == minsplits)
|
||||
continue;
|
||||
bestdistribution = distribution;
|
||||
/*
|
||||
* if equal numbers axial planes win, otherwise decide on spatial
|
||||
* subdivision
|
||||
*/
|
||||
if (splits < minsplits || (splits == minsplits && plane->type < 3)) {
|
||||
if (plane->type < 3) {
|
||||
distribution = SplitPlaneMetric(plane, mins, maxs);
|
||||
if (distribution > bestdistribution && splits == minsplits)
|
||||
continue;
|
||||
bestdistribution = distribution;
|
||||
}
|
||||
/* currently the best! */
|
||||
minsplits = splits;
|
||||
bestsurface = surf;
|
||||
}
|
||||
/* currently the best! */
|
||||
minsplits = splits;
|
||||
bestsurface = surf;
|
||||
}
|
||||
|
||||
/* If we found a candidate on first pass, don't do a second pass */
|
||||
if (bestsurface)
|
||||
break;
|
||||
}
|
||||
|
||||
return bestsurface;
|
||||
|
|
|
|||
Loading…
Reference in New Issue