/** * Duplicates the specified brush and makes it into a CSG-able level brush. * @return The new brush, or NULL if the original was empty. */ void FBSPOps::csgCopyBrush( ABrush* Dest, ABrush* Src, uint32 PolyFlags, EObjectFlags ResFlags, bool bNeedsPrep, bool bCopyPosRotScale, bool bAllowEmpty ) { check(Src); check(Src->GetBrushComponent()); check(Src->Brush); // Handle empty brush. if( !bAllowEmpty && !Src->Brush->Polys->Element.Num() ) { Dest->Brush = NULL; Dest->GetBrushComponent()->Brush = NULL; return; } // Duplicate the brush and its polys. Dest->PolyFlags = PolyFlags; Dest->Brush = NewNamedObject<UModel>(Dest, NAME_None, ResFlags); Dest->Brush->Initialize(nullptr, Src->Brush->RootOutside); Dest->Brush->Polys = NewNamedObject<UPolys>(Dest->Brush, NAME_None, ResFlags); check(Dest->Brush->Polys->Element.GetOwner()==Dest->Brush->Polys); Dest->Brush->Polys->Element.AssignButKeepOwner(Src->Brush->Polys->Element); check(Dest->Brush->Polys->Element.GetOwner()==Dest->Brush->Polys); Dest->GetBrushComponent()->Brush = Dest->Brush; if(Src->BrushBuilder != nullptr) { Dest->BrushBuilder = DuplicateObject<UBrushBuilder>(Src->BrushBuilder, Dest); } // Update poly textures. for( int32 i=0; i<Dest->Brush->Polys->Element.Num(); i++ ) { Dest->Brush->Polys->Element[i].iBrushPoly = INDEX_NONE; } // Copy positioning, and build bounding box. if(bCopyPosRotScale) { Dest->CopyPosRotScaleFrom( Src ); } // If it's a moving brush, prep it. if( bNeedsPrep ) { csgPrepMovingBrush( Dest ); } }
/** * Rotates the specified brush's vertices. */ void FBSPOps::RotateBrushVerts(ABrush* Brush, const FRotator& Rotation, bool bClearComponents) { if(Brush->BrushComponent->Brush && Brush->BrushComponent->Brush->Polys) { for( int32 poly = 0 ; poly < Brush->BrushComponent->Brush->Polys->Element.Num() ; poly++ ) { FPoly* Poly = &(Brush->BrushComponent->Brush->Polys->Element[poly]); // Rotate the vertices. for( int32 vertex = 0 ; vertex < Poly->Vertices.Num() ; vertex++ ) { Poly->Vertices[vertex] = Brush->GetPrePivot() + FRotationMatrix( Rotation ).TransformVector( Poly->Vertices[vertex] - Brush->GetPrePivot() ); } Poly->Base = Brush->GetPrePivot() + FRotationMatrix( Rotation ).TransformVector( Poly->Base - Brush->GetPrePivot() ); // Rotate the texture vectors. Poly->TextureU = FRotationMatrix( Rotation ).TransformVector( Poly->TextureU ); Poly->TextureV = FRotationMatrix( Rotation ).TransformVector( Poly->TextureV ); // Recalc the normal for the poly. Poly->Normal = FVector::ZeroVector; Poly->Finalize(Brush,0); } Brush->BrushComponent->Brush->BuildBound(); if( !Brush->IsStaticBrush() ) { csgPrepMovingBrush( Brush ); } if ( bClearComponents ) { Brush->ReregisterAllComponents(); } } }