/* * Split selected sectors in a brush in this world with one brush in other world. * (other brush must have only one sector) */ void CWorld::SplitSectors(CEntity &enThis, CBrushSectorSelection &selbscSectorsToSplit, CWorld &woOther, CEntity &enOther, const CPlacement3D &plOther) { _pfWorldEditingProfile.StartTimer(CWorldEditingProfile::PTI_CSGTOTAL); _pfWorldEditingProfile.IncrementAveragingCounter(); // assure that floating point precision is 53 bits AssureFPT_53(); // get relevant brush mip in this brush CBrushMip &bmThis = *GetBrushMip(enThis); if (&bmThis==NULL) { _pfWorldEditingProfile.StopTimer(CWorldEditingProfile::PTI_CSGTOTAL); return; } // get relevant brush mip in other brush CBrushMip &bmOther = *GetBrushMip(enOther); if (&bmOther==NULL) { _pfWorldEditingProfile.StopTimer(CWorldEditingProfile::PTI_CSGTOTAL); return; } /* Assure that the other brush has only one sector. */ // if other brush has more than one sector if (bmOther.bm_abscSectors.Count()>1) { // join all sectors of the other brush together CBrushSectorSelection selbscOtherAll; bmOther.SelectAllSectors(selbscOtherAll); woOther.JoinSectors(selbscOtherAll); } /* Split selected sectors with the one sector in the other brush. */ // get the sector of the other brush to object CBrushSectorSelectionForCSG selbscOther; bmOther.SelectAllSectors(selbscOther); CObject3D obOther; DOUBLEaabbox3D boxOther; woOther.CopySourceBrushSectorsToObject(enOther, selbscOther, plOther, obOther, enThis.en_plPlacement, boxOther); // if the selection is empty if (selbscSectorsToSplit.Count()==0) { // select all sectors near the splitting tool bmThis.SelectSectorsInRange(selbscSectorsToSplit, DOUBLEtoFLOAT(boxOther)); } // for all sectors in the selection FOREACHINDYNAMICCONTAINER(selbscSectorsToSplit, CBrushSector, itbsc) { // split the sector using the copy of other object CObject3D obj(obOther); SplitOneSector(*itbsc, obj); }
/* * Do some CSG operation with one brush in this world and one brush in other world. */ void CWorld::DoCSGOperation( CEntity &enThis, CWorld &woOther, CEntity &enOther, const CPlacement3D &plOther, void (CObject3D::*DoCSGOpenSector)(CObject3D &obA, CObject3D &obB), void (CObject3D::*DoCSGClosedSectors)(CObject3D &obA, CObject3D &obB) ) { // assure that floating point precision is 53 bits AssureFPT_53(); // get relevant brush mips in each brush CBrushMip &bmThis = *GetBrushMip(enThis); CBrushMip &bmOther = *GetBrushMip(enOther); if (&bmThis==NULL || &bmOther==NULL) { return; } // get open sector of the other brush to object CBrushSectorSelectionForCSG selbscOtherOpen; bmOther.SelectOpenSector(selbscOtherOpen); CObject3D obOtherOpen; DOUBLEaabbox3D boxOtherOpen; woOther.CopySourceBrushSectorsToObject(enOther, selbscOtherOpen, plOther, obOtherOpen, enThis.en_plPlacement, boxOtherOpen); // if there is an open sector in other object if (obOtherOpen.ob_aoscSectors.Count()>0) { CObject3D obResult; // deportalize the open sector obOtherOpen.TurnPortalsToWalls(); // if there are any sectors in this brush if (bmThis.bm_abscSectors.Count()>0) { // move affected part of this brush to an object3d object CObject3D obThis; MoveTargetBrushPartToObject(enThis, boxOtherOpen, obThis); // do the open sector CSG operation on the objects _pfWorldEditingProfile.StartTimer(CWorldEditingProfile::PTI_OBJECTCSG); (obResult.*DoCSGOpenSector)(obThis, obOtherOpen); _pfWorldEditingProfile.StopTimer(CWorldEditingProfile::PTI_OBJECTCSG); // if there are no sectors in this brush } else { // just put the open sector directly in the result obResult = obOtherOpen; } // return the result back to this brush AddObjectToBrush(obResult, enThis); } // get closed sectors of the other brush to object CBrushSectorSelectionForCSG selbscOtherClosed; bmOther.SelectClosedSectors(selbscOtherClosed); CObject3D obOtherClosed; DOUBLEaabbox3D boxOtherClosed; woOther.CopySourceBrushSectorsToObject(enOther, selbscOtherClosed, plOther, obOtherClosed, enThis.en_plPlacement, boxOtherClosed); // if there are closed sectors in other object if (obOtherClosed.ob_aoscSectors.Count()>0) { CObject3D obResult; // if there are any sectors in this brush if (bmThis.bm_abscSectors.Count()>0) { // move affected part of this brush to an object3d object CObject3D obThis; MoveTargetBrushPartToObject(enThis, boxOtherClosed, obThis); // do the closed sectors CSG operation on the objects _pfWorldEditingProfile.StartTimer(CWorldEditingProfile::PTI_OBJECTCSG); (obResult.*DoCSGClosedSectors)(obThis, obOtherClosed); _pfWorldEditingProfile.StopTimer(CWorldEditingProfile::PTI_OBJECTCSG); // if there are no sectors in this brush } else { // just put the closed sectors directly in the result obResult = obOtherClosed; } // return the result back to this brush AddObjectToBrush(obResult, enThis); } }