I was reading the CaBSP code lately. Actually everything works just fine, but I just don't understand:
Code: Select all
void BspTreeBuilderT::Build(bool IsWorldspawn, const ArrayT<Vector3dT>& FloodFillSources_,
const ArrayT<Vector3dT>& OutsidePointSamples, const std::string& MapFileName)
{
ArrayT<Vector3dT> FloodFillSources=FloodFillSources_;
MaterialT LeakDetectMat; // Just a material instance that is different from all others.
if (IsWorldspawn)
{
// Worldspawen entities are supposed to come with a flood-fill origins list provided by the caller,
// usually obtained from other entity origins (e.g. info_player_start).
assert(FloodFillSources.Size()>0);
}
else
{
assert(FloodFillSources.Size()==0);
if (FaceChildren.Size()>0)
{
// We have faces, but no flood-fill origins.
// Determine a world bounding box.
BoundingBox3T<double> WorldBB(FaceChildren[0]->Polygon.Vertices);
for (unsigned long FaceNr=1; FaceNr<FaceChildren.Size(); FaceNr++)
WorldBB.Insert(FaceChildren[FaceNr]->Polygon.Vertices);
const double d=20.0*MapT::MinVertexDist;
FloodFillSources.PushBack(WorldBB.Max+Vector3dT(d, d, d));
}
}
if (!Option_MostSimpleTree && FaceChildren.Size()>0 /*No need to try to optimize the tree if it's too simple.*/)
{
if (!Option_MinimizeFaceSplits)
{
// FIRST TREE
PrepareLeakDetection(FloodFillSources, &LeakDetectMat);
BuildBSPTree();
Portalize();
FloodFillInside(FloodFillSources, OutsidePointSamples);
if (IsWorldspawn)
{
// Only worldspawn entities are seen from the "inside", and thus supposed to be "watertight".
DetectLeaks(FloodFillSources, MapFileName, &LeakDetectMat);
}
RemoveOuterFaces();
for (unsigned long FaceNr=0; FaceNr<FaceChildren.Size(); FaceNr++)
if (FaceChildren[FaceNr]->Material==&LeakDetectMat)
{
assert(!IsWorldspawn);
delete FaceChildren[FaceNr];
FaceChildren[FaceNr]=FaceChildren[FaceChildren.Size()-1]; FaceChildren.DeleteBack();
FaceNr--;
}
// After 1st tree code.
ChopUpFaces();
}
// SECOND TREE
PrepareLeakDetection(FloodFillSources, &LeakDetectMat);
BuildBSPTree();
Portalize();
FloodFillInside(FloodFillSources, OutsidePointSamples);
if (IsWorldspawn)
{
// Only worldspawn entities are seen from the "inside", and thus supposed to be "watertight".
DetectLeaks(FloodFillSources, MapFileName, &LeakDetectMat);
}
RemoveOuterFaces();
for (unsigned long FaceNr=0; FaceNr<FaceChildren.Size(); FaceNr++)
if (FaceChildren[FaceNr]->Material==&LeakDetectMat)
{
assert(!IsWorldspawn);
delete FaceChildren[FaceNr];
FaceChildren[FaceNr]=FaceChildren[FaceChildren.Size()-1]; FaceChildren.DeleteBack();
FaceNr--;
}
// After 1st+2nd tree code.
;
}
MergeFaces();
ChopUpForMaxLightMapSize();
ChopUpForMaxSHLMapSize();
// THIRD TREE
BuildBSPTree();
if (IsWorldspawn)
{
// Do this only for worldspawn entities (seen from the "inside") for now.
//
// For other entities (seen from the "outside"), the outer portals are not built correctly with the current code.
// This is not so bad, because we don't really need a PVS for those entities anyway, but if we did, we had to make sure first
// that outer portals work right, which in turn is difficult due to their unlimited size (could limit it to the world BB though).
Portalize(); // Nur f? CaPVS!
FloodFillInside(FloodFillSources, OutsidePointSamples); // Nicht mehr wirklich n?zlich, es gibt aber noch Zusammenh?ge mit "InnerLeaf"...
/*if (IsWorldspawn)*/ RemoveOuterPortals();
}
SortFacesIntoTexNameOrder();
CreateFullBrightLightMaps();
CreateZeroBandSHLMaps();
AssignOtherChildrenToLeaves();
ComputeDrawStructures();
CreateFullVisPVS();
}