FMatrix FEditorModeTools::GetCustomDrawingCoordinateSystem() { FMatrix Matrix = FMatrix::Identity; switch (GetCoordSystem()) { case COORD_Local: { // Let the current mode have a shot at setting the local coordinate system. // If it doesn't want to, create it by looking at the currently selected actors list. bool CustomCoordinateSystemProvided = false; for (const auto& Mode : Modes) { if (Mode->GetCustomDrawingCoordinateSystem(Matrix, nullptr)) { CustomCoordinateSystemProvided = true; break; } } if (!CustomCoordinateSystemProvided) { const int32 Num = GetSelectedActors()->CountSelections<AActor>(); // Coordinate system needs to come from the last actor selected if (Num > 0) { Matrix = FRotationMatrix(GetSelectedActors()->GetBottom<AActor>()->GetActorRotation()); } } if (!Matrix.Equals(FMatrix::Identity)) { Matrix.RemoveScaling(); } } break; case COORD_World: break; default: break; } return Matrix; }
void UUnrealEdEngine::NoteSelectionChange() { // The selection changed, so make sure the pivot (widget) is located in the right place UpdatePivotLocationForSelection( true ); // Clear active editing visualizer on selection change GUnrealEd->ComponentVisManager.ClearActiveComponentVis(); TArray<FEdMode*> ActiveModes; GLevelEditorModeTools().GetActiveModes( ActiveModes ); for( int32 ModeIndex = 0; ModeIndex < ActiveModes.Num(); ++ModeIndex ) { ActiveModes[ModeIndex]->ActorSelectionChangeNotify(); } const bool bComponentSelectionChanged = GetSelectedComponentCount() > 0; USelection* Selection = bComponentSelectionChanged ? GetSelectedComponents() : GetSelectedActors(); USelection::SelectionChangedEvent.Broadcast(Selection); if (!bComponentSelectionChanged) { //whenever selection changes, recompute whether the selection contains a locked actor bCheckForLockActors = true; //whenever selection changes, recompute whether the selection contains a world info actor bCheckForWorldSettingsActors = true; UpdateFloatingPropertyWindows(); } RedrawLevelEditingViewports(); }
void UUnrealEdEngine::SelectGroup(AGroupActor* InGroupActor, bool bForceSelection/*=false*/, bool bInSelected/*=true*/, bool bNotify/*=true*/) { USelection* SelectedActors = GetSelectedActors(); SelectedActors->BeginBatchSelectOperation(); SelectedActors->Modify(); static bool bIteratingGroups = false; if( !bIteratingGroups ) { bIteratingGroups = true; // Select all actors within the group (if locked or forced) if( bForceSelection || InGroupActor->IsLocked() ) { TArray<AActor*> GroupActors; InGroupActor->GetGroupActors(GroupActors); for( int32 ActorIndex=0; ActorIndex < GroupActors.Num(); ++ActorIndex ) { SelectActor(GroupActors[ActorIndex], bInSelected, false ); } bForceSelection = true; // Recursively select any subgroups TArray<AGroupActor*> SubGroups; InGroupActor->GetSubGroups(SubGroups); for( int32 GroupIndex=0; GroupIndex < SubGroups.Num(); ++GroupIndex ) { SelectGroup(SubGroups[GroupIndex], bForceSelection, bInSelected, false); } } SelectedActors->EndBatchSelectOperation(bNotify); if (bNotify) { NoteSelectionChange(); } //whenever selection changes, recompute whether the selection contains a locked actor bCheckForLockActors = true; //whenever selection changes, recompute whether the selection contains a world info actor bCheckForWorldSettingsActors = true; bIteratingGroups = false; } }
void UUnrealEdEngine::SelectNone(bool bNoteSelectionChange, bool bDeselectBSPSurfs, bool WarnAboutManyActors) { if( GEdSelectionLock ) { return; } bool bShowProgress = false; // If there are a lot of actors to process, pop up a warning "are you sure?" box if( WarnAboutManyActors ) { int32 NumSelectedActors = GEditor->GetSelectedActorCount(); if( NumSelectedActors >= EditorActorSelectionDefs::MaxActorsToSelectBeforeWarning ) { bShowProgress = true; const FText ConfirmText = FText::Format( NSLOCTEXT("UnrealEd", "Warning_ManyActorsForDeselect", "There are {0} selected actors. Are you sure you want to deselect them all?" ), FText::AsNumber(NumSelectedActors) ); FSuppressableWarningDialog::FSetupInfo Info( ConfirmText, NSLOCTEXT( "UnrealEd", "Warning_ManyActors", "Warning: Many Actors" ), "Warning_ManyActors" ); Info.ConfirmText = NSLOCTEXT("ModalDialogs", "ManyActorsForDeselectConfirm", "Continue Deselection"); Info.CancelText = NSLOCTEXT("ModalDialogs", "ManyActorsForDeselectCancel", "Keep Current Selection"); FSuppressableWarningDialog ManyActorsWarning( Info ); if( ManyActorsWarning.ShowModal() == FSuppressableWarningDialog::Cancel ) { return; } } } if( bShowProgress ) { GWarn->BeginSlowTask( LOCTEXT("BeginDeselectingActorsTaskMessage", "Deselecting Actors"), true ); } // Make a list of selected actors . . . TArray<AActor*> ActorsToDeselect; for ( FSelectionIterator It( GetSelectedActorIterator() ) ; It ; ++It ) { AActor* Actor = static_cast<AActor*>( *It ); checkSlow( Actor->IsA(AActor::StaticClass()) ); ActorsToDeselect.Add( Actor ); } USelection* SelectedActors = GetSelectedActors(); SelectedActors->BeginBatchSelectOperation(); SelectedActors->Modify(); // . . . and deselect them. for ( int32 ActorIndex = 0 ; ActorIndex < ActorsToDeselect.Num() ; ++ActorIndex ) { AActor* Actor = ActorsToDeselect[ ActorIndex ]; SelectActor( Actor, false, false ); } uint32 NumDeselectSurfaces = 0; UWorld* World = GWorld; if( bDeselectBSPSurfs && World ) { // Unselect all surfaces in all levels. NumDeselectSurfaces += DeselectAllSurfacesForLevel( World->PersistentLevel ); for( int32 LevelIndex = 0 ; LevelIndex < World->StreamingLevels.Num() ; ++LevelIndex ) { ULevelStreaming* StreamingLevel = World->StreamingLevels[LevelIndex]; if( StreamingLevel ) { ULevel* Level = StreamingLevel->GetLoadedLevel(); if ( Level != NULL ) { NumDeselectSurfaces += DeselectAllSurfacesForLevel( Level ); } } } } SelectedActors->EndBatchSelectOperation(bNoteSelectionChange); //prevents clicking on background multiple times spamming selection changes if (ActorsToDeselect.Num() || NumDeselectSurfaces) { GetSelectedActors()->DeselectAll(); if( bNoteSelectionChange ) { NoteSelectionChange(); } //whenever selection changes, recompute whether the selection contains a locked actor bCheckForLockActors = true; //whenever selection changes, recompute whether the selection contains a world info actor bCheckForWorldSettingsActors = true; } if( bShowProgress ) { GWarn->EndSlowTask(); } }
void UUnrealEdEngine::SelectActor(AActor* Actor, bool bInSelected, bool bNotify, bool bSelectEvenIfHidden, bool bForceRefresh) { const bool bWarnIfLevelLocked = true; if( !CanSelectActor( Actor, bInSelected, bSelectEvenIfHidden, bWarnIfLevelLocked ) ) { return; } bool bSelectionHandled = false; TArray<FEdMode*> ActiveModes; GLevelEditorModeTools().GetActiveModes( ActiveModes ); for( int32 ModeIndex = 0; ModeIndex < ActiveModes.Num(); ++ModeIndex ) { bSelectionHandled |= ActiveModes[ModeIndex]->Select( Actor, bInSelected ); } // Select the actor and update its internals. if( !bSelectionHandled ) { if(bInSelected) { // If trying to select an Actor spawned by a ChildACtorComponent, instead select Actor that spawned us if(Actor->ParentComponentActor.IsValid()) { Actor = Actor->ParentComponentActor.Get(); } } if (GEditor->bGroupingActive) { // if this actor is a group, do a group select/deselect AGroupActor* SelectedGroupActor = Cast<AGroupActor>(Actor); if (SelectedGroupActor) { SelectGroup(SelectedGroupActor, true, bInSelected, bNotify); } else { // Select/Deselect this actor's entire group, starting from the top locked group. // If none is found, just use the actor. AGroupActor* ActorLockedRootGroup = AGroupActor::GetRootForActor(Actor, true); if (ActorLockedRootGroup) { SelectGroup(ActorLockedRootGroup, false, bInSelected, bNotify); } } } // Don't do any work if the actor's selection state is already the selected state. const bool bActorSelected = Actor->IsSelected(); if ( (bActorSelected && !bInSelected) || (!bActorSelected && bInSelected) ) { if(bInSelected) { UE_LOG(LogEditorSelectUtils, Verbose, TEXT("Selected Actor: %s"), *Actor->GetClass()->GetName()); } else { UE_LOG(LogEditorSelectUtils, Verbose, TEXT("Deselected Actor: %s"), *Actor->GetClass()->GetName() ); } GetSelectedActors()->Select( Actor, bInSelected ); if (!bInSelected) { if (GetSelectedComponentCount() > 0) { GetSelectedComponents()->Modify(); } for (UActorComponent* Component : Actor->GetComponents()) { GetSelectedComponents()->Deselect( Component ); // Remove the selection override delegates from the deselected components auto SceneComponent = Cast<USceneComponent>(Component); FComponentEditorUtils::BindComponentSelectionOverride(SceneComponent, false); } } else { // Bind the override delegates for the components in the selected actor for (UActorComponent* Component : Actor->GetComponents()) { auto SceneComponent = Cast<USceneComponent>(Component); FComponentEditorUtils::BindComponentSelectionOverride(SceneComponent, true); } } //A fast path to mark selection rather than reconnecting ALL components for ALL actors that have changed state SetActorSelectionFlags (Actor); if( bNotify ) { NoteSelectionChange(); } //whenever selection changes, recompute whether the selection contains a locked actor bCheckForLockActors = true; //whenever selection changes, recompute whether the selection contains a world info actor bCheckForWorldSettingsActors = true; } else { if (bNotify || bForceRefresh) { //reset the property windows. In case something has changed since previous selection UpdateFloatingPropertyWindows(bForceRefresh); } } } }
void UUnrealEdEngine::NoteActorMovement() { if( !GUndo && !(GEditor->ClickFlags & CF_MOVE_ACTOR) ) { GEditor->ClickFlags |= CF_MOVE_ACTOR; const FScopedTransaction Transaction( NSLOCTEXT("UnrealEd", "ActorMovement", "Actor Movement") ); GLevelEditorModeTools().Snapping=0; AActor* SelectedActor = NULL; for ( FSelectionIterator It( GetSelectedActorIterator() ) ; It ; ++It ) { AActor* Actor = static_cast<AActor*>( *It ); checkSlow( Actor->IsA(AActor::StaticClass()) ); SelectedActor = Actor; break; } if( SelectedActor == NULL ) { USelection* SelectedActors = GetSelectedActors(); SelectedActors->Modify(); SelectActor( GWorld->GetDefaultBrush(), true, true ); } // Look for an actor that requires snapping. for ( FSelectionIterator It( GetSelectedActorIterator() ) ; It ; ++It ) { AActor* Actor = static_cast<AActor*>( *It ); checkSlow( Actor->IsA(AActor::StaticClass()) ); GLevelEditorModeTools().Snapping = 1; break; } TSet<AGroupActor*> GroupActors; // Modify selected actors. for ( FSelectionIterator It( GetSelectedActorIterator() ) ; It ; ++It ) { AActor* Actor = static_cast<AActor*>( *It ); checkSlow( Actor->IsA(AActor::StaticClass()) ); Actor->Modify(); if (GEditor->bGroupingActive) { // if this actor is in a group, add the GroupActor into a list to be modified shortly AGroupActor* ActorLockedRootGroup = AGroupActor::GetRootForActor(Actor, true); if (ActorLockedRootGroup != nullptr) { GroupActors.Add(ActorLockedRootGroup); } } ABrush* Brush = Cast< ABrush >( Actor ); if ( Brush ) { if( Brush->Brush ) { Brush->Brush->Polys->Element.ModifyAllItems(); } } } // Modify unique group actors for (auto* GroupActor : GroupActors) { GroupActor->Modify(); } } }
void UUnrealEdEngine::UpdatePivotLocationForSelection( bool bOnChange ) { // Pick a new common pivot, or not. AActor* SingleActor = nullptr; USceneComponent* SingleComponent = nullptr; if (GetSelectedComponentCount() > 0) { for (FSelectedEditableComponentIterator It(*GetSelectedComponents()); It; ++It) { UActorComponent* Component = CastChecked<UActorComponent>(*It); AActor* ComponentOwner = Component->GetOwner(); if (ComponentOwner != nullptr) { auto SelectedActors = GetSelectedActors(); const bool bIsOwnerSelected = SelectedActors->IsSelected(ComponentOwner); check(bIsOwnerSelected); if (ComponentOwner->GetWorld() == GWorld) { SingleActor = ComponentOwner; if (Component->IsA<USceneComponent>()) { SingleComponent = CastChecked<USceneComponent>(Component); } const bool IsTemplate = ComponentOwner->IsTemplate(); const bool LevelLocked = !FLevelUtils::IsLevelLocked(ComponentOwner->GetLevel()); check(IsTemplate || LevelLocked); } } } } else { for (FSelectionIterator It(GetSelectedActorIterator()); It; ++It) { AActor* Actor = static_cast<AActor*>(*It); checkSlow(Actor->IsA(AActor::StaticClass())); if (Actor->GetWorld() == GWorld) { const bool IsTemplate = Actor->IsTemplate(); const bool LevelLocked = !FLevelUtils::IsLevelLocked(Actor->GetLevel()); check(IsTemplate || LevelLocked); SingleActor = Actor; } } } if (SingleComponent != NULL) { SetPivot(SingleComponent->GetComponentLocation(), false, true); } else if( SingleActor != NULL ) { // For geometry mode use current pivot location as it's set to selected face, not actor FEditorModeTools& Tools = GLevelEditorModeTools(); if( Tools.IsModeActive(FBuiltinEditorModes::EM_Geometry) == false || bOnChange == true ) { // Set pivot point to the actor's location FVector PivotPoint = SingleActor->GetActorLocation(); // If grouping is active, see if this actor is part of a locked group and use that pivot instead if(GEditor->bGroupingActive) { AGroupActor* ActorGroupRoot = AGroupActor::GetRootForActor(SingleActor, true, true); if(ActorGroupRoot) { PivotPoint = ActorGroupRoot->GetActorLocation(); } } SetPivot( PivotPoint, false, true ); } } else { ResetPivot(); } }
bool FLayers::RemoveSelectedActorsFromLayers( const TArray< FName >& LayerNames ) { return RemoveActorsFromLayers( GetSelectedActors(), LayerNames ); }
bool FLayers::AddSelectedActorsToLayers( const TArray< FName >& LayerNames ) { return AddActorsToLayers( GetSelectedActors(), LayerNames ); }
bool FLayers::RemoveSelectedActorsFromLayer( const FName& LayerName ) { return RemoveActorsFromLayer( GetSelectedActors(), LayerName ); }
bool FLayers::AddSelectedActorsToLayer( const FName& LayerName ) { return AddActorsToLayer( GetSelectedActors(), LayerName ); }