Esempio n. 1
0
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;
}
Esempio n. 2
0
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();
}
Esempio n. 3
0
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;
	}
}
Esempio n. 4
0
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();
	}
}
Esempio n. 5
0
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);
			}
		}
	}
}
Esempio n. 6
0
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();
		}
	}
}
Esempio n. 7
0
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();
	}
}
Esempio n. 8
0
bool FLayers::RemoveSelectedActorsFromLayers( const TArray< FName >& LayerNames )
{
	return RemoveActorsFromLayers( GetSelectedActors(), LayerNames );
}
Esempio n. 9
0
bool FLayers::AddSelectedActorsToLayers( const TArray< FName >& LayerNames )
{
	return AddActorsToLayers( GetSelectedActors(), LayerNames );
}
Esempio n. 10
0
bool FLayers::RemoveSelectedActorsFromLayer( const FName& LayerName )
{
	return RemoveActorsFromLayer( GetSelectedActors(), LayerName );
}
Esempio n. 11
0
bool FLayers::AddSelectedActorsToLayer( const FName& LayerName )
{
	return AddActorsToLayer( GetSelectedActors(), LayerName );
}