void FEdModeGeometry::PostUndo() { // Rebuild the geometry data from the current brush state GetFromSource(); // Restore selection information. for( int32 o = 0 ; o < GeomObjects.Num() ; ++o ) { int32 Idx = 0; FGeomObject* go = GeomObjects[o]; ABrush* Actor = go->GetActualBrush(); // First, clear the current selection go->SelectNone(); // Next, restore the cached selection int32 res = go->SetPivotFromSelectionArray( Actor->SavedSelections ); //use the centre of the actor if we didnt find a suitable selection if( res == INDEX_NONE ) { FEditorModeTools& Tools = GEditorModeTools(); Tools.SetPivotLocation( Actor->GetActorLocation() , false ); } go->ForceLastSelectionIndex( res ); } }
/** @return true if something was selected/deselected, false otherwise. */ bool FModeTool_GeometryModify::FrustumSelect( const FConvexVolume& InFrustum, bool InSelect /* = true */ ) { bool bResult = false; if( GEditorModeTools().IsModeActive( FBuiltinEditorModes::EM_Geometry ) ) { FEdModeGeometry* mode = (FEdModeGeometry*)GEditorModeTools().GetActiveMode( FBuiltinEditorModes::EM_Geometry ); for( FEdModeGeometry::TGeomObjectIterator Itor( mode->GeomObjectItor() ) ; Itor ; ++Itor ) { FGeomObject* go = *Itor; FTransform ActorToWorld = go->GetActualBrush()->ActorToWorld(); // Check each vertex to see if its inside the frustum for( int32 v = 0 ; v < go->VertexPool.Num() ; ++v ) { FGeomVertex& gv = go->VertexPool[v]; if( InFrustum.IntersectBox( ActorToWorld.TransformPosition( gv.GetMid() ), FVector::ZeroVector ) ) { gv.Select( InSelect ); bResult = true; } } } } return bResult; }
/** @return true if something was selected/deselected, false otherwise. */ bool FModeTool_GeometryModify::BoxSelect( FBox& InBox, bool InSelect ) { bool bResult = false; if( GEditorModeTools().IsModeActive( FBuiltinEditorModes::EM_Geometry ) ) { FEdModeGeometry* mode = (FEdModeGeometry*)GEditorModeTools().GetActiveMode( FBuiltinEditorModes::EM_Geometry ); for( FEdModeGeometry::TGeomObjectIterator Itor( mode->GeomObjectItor() ) ; Itor ; ++Itor ) { FGeomObject* go = *Itor; FTransform ActorToWorld = go->GetActualBrush()->ActorToWorld(); // Only verts for box selection for( int32 v = 0 ; v < go->VertexPool.Num() ; ++v ) { FGeomVertex& gv = go->VertexPool[v]; if( FMath::PointBoxIntersection( ActorToWorld.TransformPosition( gv.GetMid() ), InBox ) ) { gv.Select( InSelect ); bResult = true; } } } } return bResult; }
FPoly* FGeomPoly::GetActualPoly() { FGeomObject* Parent = GetParentObject(); check( Parent ); ABrush* Brush = Parent->GetActualBrush(); check( Brush ); return &( Brush->Brush->Polys->Element[ActualPolyIndex] ); }
bool FModeTool_GeometryModify::EndModify() { // Let the modifier finish up. if( CurrentModifier != NULL ) { FEdModeGeometry* mode = ((FEdModeGeometry*)GEditorModeTools().GetActiveMode(FBuiltinEditorModes::EM_Geometry)); // Update the source data to match the current geometry data. mode->SendToSource(); // Make sure the source data has remained viable. if( mode->FinalizeSourceData() ) { // If the source data was modified, reconstruct the geometry data to reflect that. mode->GetFromSource(); } CurrentModifier->EndModify(); // Update internals. for( FEdModeGeometry::TGeomObjectIterator Itor( mode->GeomObjectItor() ) ; Itor ; ++Itor ) { FGeomObject* go = *Itor; go->ComputeData(); FBSPOps::bspUnlinkPolys( go->GetActualBrush()->Brush ); // If geometry was actually changed, call PostEditBrush if(bGeomModified) { ABrush* Brush = go->GetActualBrush(); if(Brush) { if(!Brush->IsStaticBrush()) { FBSPOps::csgPrepMovingBrush(Brush); } } bGeomModified = false; } } } return 1; }
bool FEdModeGeometry::GetCustomDrawingCoordinateSystem( FMatrix& InMatrix, void* InData ) { if( GetSelectionState() == GSS_None ) { return 0; } if( InData ) { FGeomBase* GeomBase = static_cast<FGeomBase*>(InData); FGeomObject* GeomObject = GeomBase->GetParentObject(); check(GeomObject != nullptr); ABrush* Brush = GeomObject->GetActualBrush(); InMatrix = FRotationMatrix(GeomBase->GetNormal().Rotation()) * FRotationMatrix(Brush->GetActorRotation()); } else { // If we don't have a specific geometry object to get the normal from // use the one that was last selected. for( int32 o = 0 ; o < GeomObjects.Num() ; ++o ) { FGeomObject* go = GeomObjects[o]; go->CompileSelectionOrder(); if( go->SelectionOrder.Num() ) { FGeomBase* GeomBase = go->SelectionOrder[go->SelectionOrder.Num() - 1]; check(GeomBase != nullptr); FGeomObject* GeomObject = GeomBase->GetParentObject(); check(GeomObject != nullptr); ABrush* Brush = GeomObject->GetActualBrush(); InMatrix = FRotationMatrix( go->SelectionOrder[ go->SelectionOrder.Num()-1 ]->GetWidgetRotation() ) * FRotationMatrix(Brush->GetActorRotation()); return 1; } } } return 0; }