// Diese Funktion sortiert die Faces anhand ihres Texture-Namens in aufsteigender Reihenfolge. // Dank Z-Buffering kann die Engine damit die Faces in dieser Reihenfolge mit einem Minimum von State-Changes rendern. // Da außerdem die LightMaps der Faces in dieser Reihenfolge in die größeren LightMaps einsortiert werden // (CreateFullBrightLightMaps()), erhalten wir den selben positiven Effekt auch für die LightMaps! void BspTreeBuilderT::SortFacesIntoTexNameOrder() { if (FaceChildren.Size()==0) return; Console->Print(cf::va("\n%-50s %s\n", "*** Sort Faces ***", GetTimeSinceProgramStart())); FaceNrs.Clear(); for (unsigned long FaceNr=0; FaceNr<FaceChildren.Size(); FaceNr++) FaceNrs.PushBack(FaceNr); // QuickSort Faces according to their texture name. ToDoRanges.Clear(); ToDoRanges.PushBack(0); ToDoRanges.PushBack(FaceChildren.Size()-1); QuickSortFacesIntoTexNameOrder(); // Verify sorting. for (unsigned long FaceNr=0; FaceNr+1<FaceChildren.Size(); FaceNr++) if (_stricmp(FaceChildren[FaceNr]->Material->Name.c_str(), FaceChildren[FaceNr+1]->Material->Name.c_str())>0) Error("Bad sorting!"); // Wir wissen nun, daß an Stelle der Face i nun die Face FaceNrs[i] steht, wollen aber wissen, an welcher // Stelle nun die i-te Face steht. Führe dazu das RevFaceNrs-Array ein und fülle es entsprechend aus. ArrayT<unsigned long> RevFaceNrs; RevFaceNrs.PushBackEmpty(FaceChildren.Size()); for (unsigned long FaceNr=0; FaceNr<FaceChildren.Size(); FaceNr++) RevFaceNrs[FaceNrs[FaceNr]]=FaceNr; // Korrigiere damit die FaceSets der Leaves. ArrayT<cf::SceneGraph::BspTreeNodeT::LeafT>& Leaves=BspTree->Leaves; for (unsigned long LeafNr=0; LeafNr<Leaves.Size(); LeafNr++) for (unsigned long FaceNr=0; FaceNr<Leaves[LeafNr].FaceChildrenSet.Size(); FaceNr++) Leaves[LeafNr].FaceChildrenSet[FaceNr]=RevFaceNrs[Leaves[LeafNr].FaceChildrenSet[FaceNr]]; Console->Print("done\n"); }
template<class T> void Polygon3T<T>::GetChoppedUpAlong(const Polygon3T<T>& SplittingPoly, const T EdgeThickness, ArrayT< Polygon3T<T> >& NewPolys) const { Polygon3T<T> FragmentPoly=*this; NewPolys.Clear(); for (unsigned long VertexNr=0; VertexNr<SplittingPoly.Vertices.Size(); VertexNr++) { const Plane3T<T> SplitPlane=SplittingPoly.GetEdgePlane(VertexNr, EdgeThickness); if (FragmentPoly.WhatSideSimple(SplitPlane, EdgeThickness)!=Both) continue; ArrayT< Polygon3T<T> > SplitResult=FragmentPoly.GetSplits(SplitPlane, EdgeThickness); FragmentPoly=SplitResult[0]; NewPolys.PushBack(SplitResult[1]); } NewPolys.PushBack(FragmentPoly); }