qbsp: add "-midsplitsurffraction n" option as an alt. to -maxnodesize
switch to midsplit if the node contains more than this fraction of the model's total surfaces. Try 0.15 to 0.5. Works better than maxNodeSize for maps with a 3D skybox (e.g. +-128K unit maps)
This commit is contained in:
parent
a940e506ff
commit
ad65449cef
|
|
@ -358,6 +358,13 @@ public:
|
|||
int dxSubdivide;
|
||||
int dxLeakDist;
|
||||
int maxNodeSize;
|
||||
/**
|
||||
* if 0 (default), use maxNodeSize for deciding when to switch to midsplit bsp heuristic.
|
||||
*
|
||||
* if 0 < midsplitSurfFraction <=1, switch to midsplit if the node contains more than this fraction of the model's
|
||||
* total surfaces. Try 0.15 to 0.5. Works better than maxNodeSize for maps with a 3D skybox (e.g. +-128K unit maps)
|
||||
*/
|
||||
float midsplitSurfFraction;
|
||||
char szMapName[512];
|
||||
char szBSPName[512];
|
||||
char wadPath[512];
|
||||
|
|
@ -390,6 +397,7 @@ public:
|
|||
this->fixRotateObjTexture = true;
|
||||
this->fOldaxis = true;
|
||||
this->maxNodeSize = 1024;
|
||||
this->midsplitSurfFraction = 0;
|
||||
this->on_epsilon = 0.0001;
|
||||
this->worldExtent = 65536;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -854,6 +854,14 @@ ParseOptions(char *szOptions)
|
|||
if (!szTok2)
|
||||
Error("Invalid argument to option %s", szTok);
|
||||
options.maxNodeSize= atoi(szTok2);
|
||||
szTok = szTok2;
|
||||
} else if (!Q_strcasecmp(szTok, "midsplitsurffraction")) {
|
||||
szTok2 = GetTok(szTok + strlen(szTok) + 1, szEnd);
|
||||
if (!szTok2)
|
||||
Error("Invalid argument to option %s", szTok);
|
||||
options.midsplitSurfFraction = qclamp(atof(szTok2), 0.0f, 1.0f);
|
||||
logprint("Switching to midsplit when node contains more than fraction %f of model's surfaces\n", options.midsplitSurfFraction);
|
||||
|
||||
szTok = szTok2;
|
||||
} else if (!Q_strcasecmp(szTok, "epsilon")) {
|
||||
szTok2 = GetTok(szTok + strlen(szTok) + 1, szEnd);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,11 @@ static int c_solid, c_empty, c_water, c_detail, c_detail_illusionary, c_detail_f
|
|||
static int c_illusionary_visblocker;
|
||||
static bool usemidsplit;
|
||||
|
||||
/**
|
||||
* Total number of surfaces in the map
|
||||
*/
|
||||
static int mapsurfaces;
|
||||
|
||||
//============================================================================
|
||||
|
||||
void
|
||||
|
|
@ -508,13 +513,24 @@ SelectPartition(surface_t *surfaces)
|
|||
maxs[i] = surf->maxs[i];
|
||||
}
|
||||
|
||||
bool largenode = false;
|
||||
if (options.maxNodeSize >= 64) {
|
||||
const vec_t maxnodesize = options.maxNodeSize - ON_EPSILON;
|
||||
// how much of the map are we partitioning?
|
||||
double fractionOfMap = surfcount / (double)mapsurfaces;
|
||||
|
||||
largenode = (maxs[0] - mins[0]) > maxnodesize
|
||||
|| (maxs[1] - mins[1]) > maxnodesize
|
||||
|| (maxs[2] - mins[2]) > maxnodesize;
|
||||
bool largenode = false;
|
||||
|
||||
// decide if we should switch to the midsplit method
|
||||
if (options.midsplitSurfFraction != 0.0) {
|
||||
// new way (opt-in)
|
||||
largenode = (fractionOfMap > options.midsplitSurfFraction);
|
||||
} else {
|
||||
// old way (ericw-tools 0.15.2+)
|
||||
if (options.maxNodeSize >= 64) {
|
||||
const vec_t maxnodesize = options.maxNodeSize - ON_EPSILON;
|
||||
|
||||
largenode = (maxs[0] - mins[0]) > maxnodesize
|
||||
|| (maxs[1] - mins[1]) > maxnodesize
|
||||
|| (maxs[2] - mins[2]) > maxnodesize;
|
||||
}
|
||||
}
|
||||
|
||||
if (usemidsplit || largenode) // do fast way for clipping hull
|
||||
|
|
@ -1044,6 +1060,11 @@ SolidBSP(const mapentity_t *entity, surface_t *surfhead, bool midsplit)
|
|||
c_detail_illusionary = 0;
|
||||
c_detail_fence = 0;
|
||||
c_illusionary_visblocker = 0;
|
||||
// count map surfaces; this is used when deciding to switch between midsplit and the expensive partitioning
|
||||
mapsurfaces = 0;
|
||||
for (surface_t *surf = surfhead; surf; surf = surf->next) {
|
||||
mapsurfaces++;
|
||||
}
|
||||
|
||||
PartitionSurfaces(surfhead, headnode);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue