229 lines
6.2 KiB
C++
229 lines
6.2 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "StreamingLevels/StreamingLevelEdMode.h"
|
|
#include "Engine/LevelStreaming.h"
|
|
#include "EditorViewportClient.h"
|
|
#include "Materials/Material.h"
|
|
#include "Materials/MaterialInstanceDynamic.h"
|
|
#include "LevelUtils.h"
|
|
#include "ActorEditorUtils.h"
|
|
#include "GameFramework/WorldSettings.h"
|
|
|
|
#define LOCTEXT_NAMESPACE "WorldBrowser"
|
|
|
|
/** Constructor */
|
|
FStreamingLevelEdMode::FStreamingLevelEdMode()
|
|
: FEdMode()
|
|
{
|
|
UMaterial* GizmoMaterial = (UMaterial*)StaticLoadObject( UMaterial::StaticClass(),NULL,TEXT("/Engine/EditorMaterials/LevelTransformMaterial.LevelTransformMaterial") );
|
|
BoxMaterial = UMaterialInstanceDynamic::Create( GizmoMaterial, NULL );
|
|
|
|
bIsTracking = false;
|
|
}
|
|
|
|
/** Destructor */
|
|
FStreamingLevelEdMode::~FStreamingLevelEdMode()
|
|
{
|
|
|
|
}
|
|
|
|
void FStreamingLevelEdMode::AddReferencedObjects( FReferenceCollector& Collector )
|
|
{
|
|
// Call parent implementation
|
|
FEdMode::AddReferencedObjects( Collector );
|
|
|
|
Collector.AddReferencedObject(BoxMaterial);
|
|
}
|
|
|
|
EAxisList::Type FStreamingLevelEdMode::GetWidgetAxisToDraw( UE::Widget::EWidgetMode InWidgetMode ) const
|
|
{
|
|
switch(InWidgetMode)
|
|
{
|
|
case UE::Widget::WM_Translate:
|
|
return EAxisList::XYZ;
|
|
case UE::Widget::WM_Rotate:
|
|
return EAxisList::Z;
|
|
case UE::Widget::WM_Scale:
|
|
return EAxisList::None;
|
|
default:
|
|
return EAxisList::None;
|
|
}
|
|
}
|
|
|
|
bool FStreamingLevelEdMode::ShouldDrawWidget() const
|
|
{
|
|
return SelectedLevel.IsValid();
|
|
}
|
|
|
|
bool FStreamingLevelEdMode::UsesTransformWidget( UE::Widget::EWidgetMode CheckMode ) const
|
|
{
|
|
if( CheckMode == UE::Widget::EWidgetMode::WM_Scale )
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
FVector FStreamingLevelEdMode::GetWidgetLocation() const
|
|
{
|
|
if (SelectedLevel.IsValid())
|
|
{
|
|
return LevelTransform.GetTranslation();
|
|
}
|
|
return FEdMode::GetWidgetLocation();
|
|
}
|
|
|
|
void FStreamingLevelEdMode::SetLevel( ULevelStreaming* LevelStream )
|
|
{
|
|
if( SelectedLevel.IsValid() && SelectedLevel.Get() != LevelStream )
|
|
{
|
|
// Changed level need to apply PostEditMove to the actors we moved in the last level
|
|
ApplyPostEditMove();
|
|
}
|
|
|
|
SelectedLevel = LevelStream;
|
|
bIsDirty = false;
|
|
if ( SelectedLevel.IsValid() )
|
|
{
|
|
LevelTransform = SelectedLevel->LevelTransform;
|
|
ULevel* Level = SelectedLevel->GetLoadedLevel();
|
|
|
|
|
|
// Calculate the Level bounds box
|
|
LevelBounds = FBox(ForceInit);
|
|
|
|
if( Level )
|
|
{
|
|
for( int32 ActorIndex=0; ActorIndex< Level->Actors.Num(); ActorIndex++ )
|
|
{
|
|
AActor* Actor = Level->Actors[ActorIndex];
|
|
|
|
// Don't include the builder brush or the world settings as they can artificially make the level bounds bigger
|
|
if( Actor && FActorEditorUtils::IsABuilderBrush(Actor) == false && Level->GetWorldSettings() != Actor )
|
|
{
|
|
LevelBounds += Actor->GetComponentsBoundingBox();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
GEditor->RedrawAllViewports();
|
|
}
|
|
|
|
bool FStreamingLevelEdMode::InputDelta( FEditorViewportClient* InViewportClient, FViewport* InViewport, FVector& InDrag, FRotator& InRot, FVector& InScale )
|
|
{
|
|
// Only Update the LevelTransform if the user has clicked on the Widget
|
|
if (InViewportClient->GetCurrentWidgetAxis() != EAxisList::None)
|
|
{
|
|
FVector Translation = LevelTransform.GetTranslation();
|
|
Translation += InDrag;
|
|
LevelTransform.SetTranslation( Translation );
|
|
|
|
FRotator Rot = LevelTransform.GetRotation().Rotator();
|
|
Rot += InRot;
|
|
LevelTransform.SetRotation( Rot.Quaternion() );
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void FStreamingLevelEdMode::Render( const FSceneView* View, FViewport* Viewport, FPrimitiveDrawInterface* PDI )
|
|
{
|
|
FEdMode::Render( View, Viewport, PDI );
|
|
|
|
if( SelectedLevel.IsValid() )
|
|
{
|
|
if( !bIsTracking && !LevelTransform.Equals( SelectedLevel->LevelTransform ) )
|
|
{
|
|
// Level has changed outside of this tool, probably and undo, need to match up the widget again
|
|
LevelBounds.Min -= ( LevelTransform.GetLocation() - SelectedLevel->LevelTransform.GetLocation() );
|
|
LevelBounds.Max -= ( LevelTransform.GetLocation() - SelectedLevel->LevelTransform.GetLocation() );
|
|
LevelTransform = SelectedLevel->LevelTransform;
|
|
}
|
|
|
|
FTransform BoxTransform = LevelTransform;
|
|
FVector BoxLocation = ( LevelBounds.GetCenter() ) + ( LevelTransform.GetLocation() - SelectedLevel->LevelTransform.GetLocation() );
|
|
BoxTransform.SetLocation( BoxLocation );
|
|
DrawBox( PDI, BoxTransform.ToMatrixWithScale(), LevelBounds.GetExtent(), BoxMaterial->GetRenderProxy(), SDPG_World );
|
|
}
|
|
}
|
|
|
|
bool FStreamingLevelEdMode::StartTracking( FEditorViewportClient* InViewportClient, FViewport* InViewport )
|
|
{
|
|
bIsTracking = true;
|
|
return true;
|
|
}
|
|
|
|
bool FStreamingLevelEdMode::EndTracking( FEditorViewportClient* InViewportClient, FViewport* InViewport )
|
|
{
|
|
bIsTracking = false;
|
|
if( SelectedLevel.IsValid() && !LevelTransform.Equals( SelectedLevel->LevelTransform ) )
|
|
{
|
|
bIsDirty = true;
|
|
// Update Level bounds as its now in a new location
|
|
LevelBounds.Min += ( LevelTransform.GetLocation() - SelectedLevel->LevelTransform.GetLocation() );
|
|
LevelBounds.Max += ( LevelTransform.GetLocation() - SelectedLevel->LevelTransform.GetLocation() );
|
|
|
|
// Only update the level transform when the user releases the mouse button
|
|
FLevelUtils::SetEditorTransform( SelectedLevel.Get(), LevelTransform, false );
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void FStreamingLevelEdMode::Enter()
|
|
{
|
|
FEdMode::Enter();
|
|
FWorldDelegates::LevelRemovedFromWorld.AddSP(this, &FStreamingLevelEdMode::OnLevelRemovedFromWorld);
|
|
}
|
|
|
|
void FStreamingLevelEdMode::Exit()
|
|
{
|
|
FWorldDelegates::LevelRemovedFromWorld.RemoveAll(this);
|
|
ApplyPostEditMove();
|
|
SelectedLevel = NULL;
|
|
FEdMode::Exit();
|
|
}
|
|
|
|
void FStreamingLevelEdMode::ApplyPostEditMove()
|
|
{
|
|
if( SelectedLevel.IsValid() && bIsDirty )
|
|
{
|
|
ULevel* LoadedLevel = SelectedLevel->GetLoadedLevel();
|
|
if( LoadedLevel != NULL )
|
|
{
|
|
FLevelUtils::ApplyPostEditMove(LoadedLevel);
|
|
bIsDirty = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool FStreamingLevelEdMode::IsEditing( ULevelStreaming* Level )
|
|
{
|
|
return Level == SelectedLevel.Get();
|
|
}
|
|
|
|
bool FStreamingLevelEdMode::IsSnapRotationEnabled()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool FStreamingLevelEdMode::SnapRotatorToGridOverride( FRotator& Rotation )
|
|
{
|
|
//Rotation = Rotation.GridSnap( FRotator( 90, 90, 90 ) );
|
|
return true;
|
|
}
|
|
|
|
void FStreamingLevelEdMode::OnLevelRemovedFromWorld(ULevel* InLevel, UWorld* InWorld)
|
|
{
|
|
if (SelectedLevel.IsValid())
|
|
{
|
|
if (SelectedLevel->GetLoadedLevel() == InLevel)
|
|
{
|
|
SelectedLevel = NULL;
|
|
Exit();
|
|
}
|
|
}
|
|
}
|
|
|
|
#undef LOCTEXT_NAMESPACE
|