UK2Node_PlayMovieScene* FSequencerActorBindingManager::CreateNewPlayMovieSceneNode( UMovieScene* MovieScene ) const { // Grab the world object for this editor check( MovieScene != NULL ); ULevel* Level = ActorWorld->GetCurrentLevel(); check( Level != NULL ); // Here, we'll create a level script if one does not yet exist. const bool bDontCreate = false; ULevelScriptBlueprint* LSB = Level->GetLevelScriptBlueprint( bDontCreate ); if( LSB != NULL ) { UEdGraph* TargetGraph = NULL; if( LSB->UbergraphPages.Num() > 0 ) { TargetGraph = LSB->UbergraphPages[0]; // Just use the first graph } if( ensure( TargetGraph != NULL ) ) { // Figure out a decent place to stick the node const FVector2D NewNodePos = TargetGraph->GetGoodPlaceForNewNode(); // Create a new node UK2Node_PlayMovieScene* TemplateNode = NewObject<UK2Node_PlayMovieScene>(); TemplateNode->SetMovieScene( MovieScene ); return FEdGraphSchemaAction_K2NewNode::SpawnNodeFromTemplate<UK2Node_PlayMovieScene>(TargetGraph, TemplateNode, NewNodePos);; } } return NULL; }
void UUnrealEdEngine::MakeSelectedActorsLevelCurrent() { ULevel* LevelToMakeCurrent = NULL; // Look to the selected actors for the level to make current. // If actors from multiple levels are selected, do nothing. for ( FSelectionIterator It( GetSelectedActorIterator() ) ; It ; ++It ) { AActor* Actor = static_cast<AActor*>( *It ); checkSlow( Actor->IsA(AActor::StaticClass()) ); ULevel* ActorLevel = Actor->GetLevel(); if ( !LevelToMakeCurrent ) { // First assignment. LevelToMakeCurrent = ActorLevel; } else if ( LevelToMakeCurrent != ActorLevel ) { // Actors from multiple levels are selected -- abort. LevelToMakeCurrent = NULL; break; } } // Change the current level to something different if ( LevelToMakeCurrent && !LevelToMakeCurrent->IsCurrentLevel() ) { EditorLevelUtils::MakeLevelCurrent( LevelToMakeCurrent ); } }
bool ALevelScriptActor::RemoteEvent(FName EventName) { bool bFoundEvent = false; // Iterate over all levels, and try to find a matching function on the level's script actor for( TArray<ULevel*>::TConstIterator it = GetWorld()->GetLevels().CreateConstIterator(); it; ++it ) { ULevel* CurLevel = *it; if( CurLevel ) { ALevelScriptActor* LSA = CurLevel->GetLevelScriptActor(); if( LSA ) { // Find an event with no parameters UFunction* EventTarget = LSA->FindFunction(EventName); if( EventTarget && EventTarget->NumParms == 0) { LSA->ProcessEvent(EventTarget, NULL); bFoundEvent = true; } } } } return bFoundEvent; }
void FEdModeLevel::SetLevel( ULevelStreaming* LevelStream ) { if( SelectedLevel != NULL && SelectedLevel != LevelStream ) { // Changed level need to apply PostEditMove to the actors we moved in the last level ApplyPostEditMove(); } SelectedLevel = LevelStream; bIsDirty = false; if( SelectedLevel ) { LevelTransform = SelectedLevel->LevelTransform; ULevel* Level = SelectedLevel->GetLoadedLevel(); // Calculate the Level bounds box LevelBounds = FBox(0); 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(); }
FFoliageInstanceBaseId FFoliageInstanceBaseCache::AddInstanceBaseId(UActorComponent* InComponent) { FFoliageInstanceBaseId BaseId = FFoliageInstanceBaseCache::InvalidBaseId; if (InComponent && !InComponent->IsCreatedByConstructionScript()) { BaseId = GetInstanceBaseId(InComponent); if (BaseId == FFoliageInstanceBaseCache::InvalidBaseId) { BaseId = NextBaseId++; FFoliageInstanceBaseInfo BaseInfo(InComponent); InstanceBaseMap.Add(BaseId, BaseInfo); InstanceBaseInvMap.Add(BaseInfo.BasePtr, BaseId); check(InstanceBaseMap.Num() == InstanceBaseInvMap.Num()); ULevel* ComponentLevel = InComponent->GetComponentLevel(); if (ComponentLevel) { UWorld* ComponentWorld = Cast<UWorld>(ComponentLevel->GetOuter()); if (ComponentWorld) { auto WorldKey = TAssetPtr<UWorld>(ComponentWorld); InstanceBaseLevelMap.FindOrAdd(WorldKey).Add(BaseInfo.BasePtr); } } } } return BaseId; }
void FLevelModel::SetVisible(bool bVisible) { //don't create unnecessary transactions if (IsVisible() == bVisible) { return; } const bool oldIsDirty = IsDirty(); const FScopedTransaction Transaction(LOCTEXT("ToggleVisibility", "Toggle Level Visibility")); //this call hides all owned actors, etc EditorLevelUtils::SetLevelVisibility( GetLevelObject(), bVisible, false ); if (!oldIsDirty) { // don't set the dirty flag if we're just changing the visibility of the level within the editor ULevel* Level = GetLevelObject(); if (Level) { Level->GetOutermost()->SetDirtyFlag(false); } } }
/** Generates a sub-level Blueprints sub-menu */ static void MakeSubLevelsMenu(FMenuBuilder& InMenuBuilder, TWeakPtr< SLevelEditor > InLvlEditor) { FSlateIcon EditBP(FEditorStyle::Get().GetStyleSetName(), TEXT("LevelEditor.OpenLevelBlueprint")); InMenuBuilder.BeginSection(NAME_None, LOCTEXT("SubLevelsHeading", "Sub-Level Blueprints")); { UWorld* World = InLvlEditor.Pin()->GetWorld(); for (int32 iLevel = 0; iLevel < World->GetNumLevels(); iLevel++) { ULevel* Level = World->GetLevel(iLevel); if (Level != NULL && Level->GetOutermost() != NULL) { if (!Level->IsPersistentLevel()) { FUIAction UIAction ( FExecuteAction::CreateStatic(&FLevelEditorToolBar::OnOpenSubLevelBlueprint, Level) ); FText DisplayName = FText::Format(LOCTEXT("SubLevelBlueprintItem", "Edit {LevelName}"), FText::FromString(FPaths::GetCleanFilename(Level->GetOutermost()->GetName()))); InMenuBuilder.AddMenuEntry(DisplayName, FText::GetEmpty(), EditBP, UIAction); } } } } InMenuBuilder.EndSection(); }
ULevelStreaming* FWorldTileModel::CreateAssosiatedStreamingLevel() { ULevelStreaming* AssociatedStreamingLevel = NULL; ULevel* Level = GetLevelObject(); if (Level) { FName PackageName = Level->GetOutermost()->GetFName(); UWorld* PersistentWorld = LevelCollectionModel.GetWorld(); // Try to find existing object first int32 FoundIndex = PersistentWorld->StreamingLevels.FindMatch(ULevelStreaming::FPackageNameMatcher(PackageName)); if (FoundIndex != INDEX_NONE) { AssociatedStreamingLevel = PersistentWorld->StreamingLevels[FoundIndex]; } else { // Create new streaming level AssociatedStreamingLevel = Cast<ULevelStreaming>( StaticConstructObject(ULevelStreamingKismet::StaticClass(), PersistentWorld, NAME_None, RF_Transient, NULL) ); // AssociatedStreamingLevel->PackageName = PackageName; AssociatedStreamingLevel->DrawColor = FColor::MakeRandomColor(); AssociatedStreamingLevel->LevelTransform = FTransform::Identity; AssociatedStreamingLevel->PackageNameToLoad = PackageName; // PersistentWorld->StreamingLevels.Add(AssociatedStreamingLevel); } } return AssociatedStreamingLevel; }
void ALevelBounds::BroadcastLevelBoundsUpdated() { ULevel* Level = GetLevel(); if (Level && Level->LevelBoundsActor.Get() == this) { Level->BroadcastLevelBoundsActorUpdated(); } }
FSlateTextureDataPtr FTileThumbnail::UpdateThumbnail() { // No need images for persistent and always loaded levels if (TileModel.IsPersistent()) { return ToSlateTextureData(nullptr); } // Load image from a package header if (!TileModel.IsVisible() || TileModel.IsSimulating()) { const FName LevelAssetName = TileModel.GetAssetName(); TSet<FName> ObjectFullNames; ObjectFullNames.Add(LevelAssetName); FThumbnailMap ThumbnailMap; if (ThumbnailTools::ConditionallyLoadThumbnailsFromPackage(TileModel.GetPackageFileName(), ObjectFullNames, ThumbnailMap)) { const FObjectThumbnail* ObjectThumbnail = ThumbnailMap.Find(LevelAssetName); return ToSlateTextureData(ObjectThumbnail); } } // Render image from a visible level else { ULevel* TargetLevel = TileModel.GetLevelObject(); if (TargetLevel) { FIntPoint RTSize = ThumbnailRenderTarget->GetSizeXY(); // Set persistent world package as transient to avoid package dirtying during thumbnail rendering FUnmodifiableObject ImmuneWorld(TargetLevel->OwningWorld); FObjectThumbnail NewThumbnail; // Generate the thumbnail ThumbnailTools::RenderThumbnail( TargetLevel, RTSize.X, RTSize.Y, ThumbnailTools::EThumbnailTextureFlushMode::NeverFlush, ThumbnailRenderTarget, &NewThumbnail ); UPackage* MyOutermostPackage = CastChecked<UPackage>(TargetLevel->GetOutermost()); ThumbnailTools::CacheThumbnail(TileModel.GetAssetName().ToString(), &NewThumbnail, MyOutermostPackage); return ToSlateTextureData(&NewThumbnail); } } return ToSlateTextureData(nullptr); }
EVisibility SWorldHierarchyItem::GetColorButtonVisibility() const { EVisibility Result = EVisibility::Hidden; if (LevelModel.IsValid()) { ULevel* LevelObject = LevelModel->GetLevelObject(); if (LevelObject && !LevelObject->IsPersistentLevel()) { Result = EVisibility::Visible; } } return Result; }
/** Restores systems that need references to classes in the renderer module. */ void RestoreReferencesToRendererModuleClasses( const TMap<UWorld*, bool>& WorldsToUpdate, const TMap<FMaterialShaderMap*, TScopedPointer<TArray<uint8> > >& ShaderMapToSerializedShaderData, const TScopedPointer<TArray<uint8> >& GlobalShaderData, const TMap<FShaderType*, FString>& ShaderTypeNames, const TMap<FVertexFactoryType*, FString>& VertexFactoryTypeNames) { FlushShaderFileCache(); // Initialize cached shader type data InitializeShaderTypes(); IRendererModule& RendererModule = GetRendererModule(); FSceneViewStateReference::AllocateAll(); // Recreate all renderer scenes for (TMap<UWorld*, bool>::TConstIterator It(WorldsToUpdate); It; ++It) { UWorld* World = It.Key(); RendererModule.AllocateScene(World, World->RequiresHitProxies(), It.Value(), World->FeatureLevel); for (int32 LevelIndex = 0; LevelIndex < World->GetNumLevels(); LevelIndex++) { ULevel* Level = World->GetLevel(LevelIndex); Level->InitializeRenderingResources(); } } // Restore FShaders from the serialized memory blobs // Shader maps may still not be complete after this due to code changes picked up in the recompile RestoreGlobalShaderMap(GRHIShaderPlatform_DEPRECATED, *GlobalShaderData); UMaterial::RestoreMaterialShadersFromMemory(GRHIShaderPlatform_DEPRECATED, ShaderMapToSerializedShaderData); FMaterialShaderMap::FixupShaderTypes(GRHIShaderPlatform_DEPRECATED, ShaderTypeNames, VertexFactoryTypeNames); TArray<FShaderType*> OutdatedShaderTypes; TArray<const FVertexFactoryType*> OutdatedFactoryTypes; FShaderType::GetOutdatedTypes(OutdatedShaderTypes, OutdatedFactoryTypes); // Recompile any missing shaders UMaterialInterface::IterateOverActiveFeatureLevels([&](ERHIFeatureLevel::Type FeatureLevel) { auto ShaderPlatform = GShaderPlatformForFeatureLevel[FeatureLevel]; BeginRecompileGlobalShaders(OutdatedShaderTypes, ShaderPlatform); UMaterial::UpdateMaterialShaders(OutdatedShaderTypes, OutdatedFactoryTypes, ShaderPlatform); }); // Block on global shader jobs FinishRecompileGlobalShaders(); }
/** * Assembles the set of all referenced worlds. * * @param OutWorlds [out] The set of referenced worlds. * @param bIncludeGWorld If true, include GWorld in the output list. * @param bOnlyEditorVisible If true, only sub-levels that should be visible in-editor are included */ void GetWorlds(UWorld* InWorld, TArray<UWorld*>& OutWorlds, bool bIncludeInWorld, bool bOnlyEditorVisible) { OutWorlds.Empty(); if ( bIncludeInWorld ) { OutWorlds.AddUnique( InWorld ); } // Iterate over the world's level array to find referenced levels ("worlds"). We don't for ( int32 LevelIndex = 0 ; LevelIndex < InWorld->StreamingLevels.Num() ; ++LevelIndex ) { ULevelStreaming* StreamingLevel = InWorld->StreamingLevels[LevelIndex]; if ( StreamingLevel ) { // If we asked for only sub-levels that are editor-visible, then limit our results appropriately bool bShouldAlwaysBeLoaded = false; // Cast< ULevelStreamingAlwaysLoaded >( StreamingLevel ) != NULL; if( !bOnlyEditorVisible || bShouldAlwaysBeLoaded || StreamingLevel->bShouldBeVisibleInEditor ) { const ULevel* Level = StreamingLevel->GetLoadedLevel(); // This should always be the case for valid level names as the Editor preloads all packages. if ( Level != NULL ) { // Newer levels have their packages' world as the outer. UWorld* World = Cast<UWorld>( Level->GetOuter() ); if ( World != NULL ) { OutWorlds.AddUnique( World ); } } } } } // Levels can be loaded directly without StreamingLevel facilities for ( int32 LevelIndex = 0 ; LevelIndex < InWorld->GetLevels().Num() ; ++LevelIndex ) { ULevel* Level = InWorld->GetLevel(LevelIndex); if ( Level ) { // Newer levels have their packages' world as the outer. UWorld* World = Cast<UWorld>( Level->GetOuter() ); if ( World != NULL ) { OutWorlds.AddUnique( World ); } } } }
TArray<UPackage*> FLevelCollectionModel::GetPackagesList(const FLevelModelList& InList) { TArray<UPackage*> ResultList; for (auto It = InList.CreateConstIterator(); It; ++It) { ULevel* Level = (*It)->GetLevelObject(); if (Level) { ResultList.Add(Level->GetOutermost()); } } return ResultList; }
void FWorldTileModel::SetLevelPosition(const FIntPoint& InPosition) { // Parent absolute position TSharedPtr<FWorldTileModel> ParentModel = StaticCastSharedPtr<FWorldTileModel>(GetParent()); FIntPoint ParentAbsolutePostion = ParentModel.IsValid() ? ParentModel->GetAbsoluteLevelPosition() : FIntPoint::ZeroValue; // Actual offset FIntPoint Offset = InPosition - TileDetails->AbsolutePosition; // Update absolute position TileDetails->AbsolutePosition = InPosition; // Assign new position as relative to parent TileDetails->Position = TileDetails->AbsolutePosition - ParentAbsolutePostion; // Flush changes to level package OnLevelInfoUpdated(); // Move actors if necessary ULevel* Level = GetLevelObject(); if (Level != NULL && Level->bIsVisible) { // Shelve level, if during this translation level will end up out of Editable area if (!ShouldBeVisible(LevelCollectionModel.EditableWorldArea())) { Shelve(); } // Move actors if (Offset != FIntPoint::ZeroValue) { Level->ApplyWorldOffset(FVector(Offset), false); } } if (IsLandscapeBased()) { FixLandscapeSectionsOffset(); } // Transform child levels for (auto It = AllChildren.CreateIterator(); It; ++It) { TSharedPtr<FWorldTileModel> ChildModel = StaticCastSharedPtr<FWorldTileModel>(*It); FIntPoint ChildPosition = TileDetails->AbsolutePosition + ChildModel->GetRelativeLevelPosition(); ChildModel->SetLevelPosition(ChildPosition); } }
FString FLevelModel::GetFileSizeString() const { FString MemorySizeString; ULevel* Level = GetLevelObject(); if (Level && Editor->AccessEditorUserSettings().bDisplayFileSizeInLevelBrowser) { // Update metrics static const float ByteConversion = 1.0f / 1024.0f; float FileSize = Level->GetOutermost()->GetFileSize() * ByteConversion * ByteConversion; MemorySizeString += FString::Printf(TEXT( "%.2f" ), FileSize); } return MemorySizeString; }
FString FLevelViewModel::GetFileSizeString() const { FString MemorySizeString; ULevel* CurLevel = Level.Get(); if ( CurLevel && GetDefault<ULevelBrowserSettings>()->bDisplayFileSize ) { // Update metrics static const float ByteConversion = 1.0f / 1024.0f; float FileSize = CurLevel->GetOutermost()->GetFileSize() * ByteConversion * ByteConversion; MemorySizeString += FString::Printf( TEXT( "%.2f" ), FileSize ); } return MemorySizeString; }
void FLevelCollectionModel::CacheCanExecuteSourceControlVars() const { bCanExecuteSCCCheckOut = false; bCanExecuteSCCOpenForAdd = false; bCanExecuteSCCCheckIn = false; bCanExecuteSCC = false; ISourceControlProvider& SourceControlProvider = ISourceControlModule::Get().GetProvider(); for (auto It = SelectedLevelsList.CreateConstIterator(); It; ++It) { if (ISourceControlModule::Get().IsEnabled() && SourceControlProvider.IsAvailable()) { bCanExecuteSCC = true; ULevel* Level = (*It)->GetLevelObject(); if (Level) { // Check the SCC state for each package in the selected paths FSourceControlStatePtr SourceControlState = SourceControlProvider.GetState(Level->GetOutermost(), EStateCacheUsage::Use); if (SourceControlState.IsValid()) { if (SourceControlState->CanCheckout()) { bCanExecuteSCCCheckOut = true; } else if (!SourceControlState->IsSourceControlled()) { bCanExecuteSCCOpenForAdd = true; } else if (SourceControlState->IsCheckedOut() || SourceControlState->IsAdded()) { bCanExecuteSCCCheckIn = true; } } } } if (bCanExecuteSCCCheckOut && bCanExecuteSCCOpenForAdd && bCanExecuteSCCCheckIn) { // All options are available, no need to keep iterating break; } } }
void FLevelViewModel::ChangeColor(const TSharedRef<SWidget>& InPickerParentWidget) { if( !Level.IsValid() ) { return; } if ( !Level->IsPersistentLevel()) { // Initialize the color data for the picker window. ULevelStreaming* StreamingLevel = FLevelUtils::FindStreamingLevel( Level.Get() ); check( StreamingLevel ); FLinearColor NewColor = StreamingLevel->LevelColor; TArray<FLinearColor*> ColorArray; ColorArray.Add(&NewColor); FColorPickerArgs PickerArgs; PickerArgs.bIsModal = true; PickerArgs.DisplayGamma = TAttribute<float>::Create( TAttribute<float>::FGetter::CreateUObject(GEngine, &UEngine::GetDisplayGamma) ); PickerArgs.LinearColorArray = &ColorArray; PickerArgs.OnColorPickerCancelled = FOnColorPickerCancelled::CreateSP(this, &FLevelViewModel::OnColorPickerCancelled); PickerArgs.ParentWidget = InPickerParentWidget; // ensure this is true, will be set to false in OnColorPickerCancelled if necessary bColorPickerOK = true; if (OpenColorPicker(PickerArgs)) { if ( bColorPickerOK ) { StreamingLevel->LevelColor = NewColor; StreamingLevel->Modify(); // Update the loaded level's components so the change in color will apply immediately ULevel* LoadedLevel = StreamingLevel->GetLoadedLevel(); if ( LoadedLevel ) { LoadedLevel->UpdateLevelComponents(false); } ULevel::LevelDirtiedEvent.Broadcast(); } FEditorSupportDelegates::RedrawAllViewports.Broadcast(); } } }
/** Check if the object is in a visible level */ bool IsInVisibleLevel( UObject* InObject, UWorld* InWorld ) const { check( InObject ); check( InWorld ); UObject* ObjectPackage = InObject->GetOutermost(); for( int32 LevelIndex=0; LevelIndex<InWorld->GetNumLevels(); LevelIndex++ ) { ULevel* Level = InWorld->GetLevel(LevelIndex); if( Level && Level->GetOutermost() == ObjectPackage ) { return true; } } return false; }
void UUnrealEdEngine::ConvertMatinees() { FVector StartLocation= FVector::ZeroVector; UWorld* World = GWorld; if( World ) { ULevel* Level = World->GetCurrentLevel(); if( !Level ) { Level = World->PersistentLevel; } check(Level); for( TObjectIterator<UInterpData> It; It; ++It ) { UInterpData* InterpData = *It; if( InterpData->IsIn( Level ) ) { // We dont care about renaming references or adding redirectors. References to this will be old seqact_interps GEditor->RenameObject( InterpData, Level->GetOutermost(), *InterpData->GetName() ); AMatineeActor* MatineeActor = Level->OwningWorld->SpawnActor<AMatineeActor>(StartLocation, FRotator::ZeroRotator); StartLocation.Y += 50; MatineeActor->MatineeData = InterpData; UProperty* MatineeDataProp = NULL; for( UProperty* Property = MatineeActor->GetClass()->PropertyLink; Property != NULL; Property = Property->PropertyLinkNext ) { if( Property->GetName() == TEXT("MatineeData") ) { MatineeDataProp = Property; break; } } FPropertyChangedEvent PropertyChangedEvent( MatineeDataProp ); MatineeActor->PostEditChangeProperty( PropertyChangedEvent ); } } } }
void FLevelModel::OpenKismet() { if (LevelCollectionModel.IsReadOnly()) { return; } ULevel* Level = GetLevelObject(); if (Level == NULL) { return; } ULevelScriptBlueprint* LevelScriptBlueprint = Level->GetLevelScriptBlueprint(); if (LevelScriptBlueprint) { FAssetEditorManager::Get().OpenEditorForAsset(LevelScriptBlueprint); } else { FMessageDialog::Open(EAppMsgType::Ok, NSLOCTEXT("UnrealEd", "UnableToCreateLevelScript", "Unable to find or create a level blueprint for this level.") ); } }
void FWorldTileModel::OnStreamingLevelsPropertyChanged() { ULevel* Level = GetLevelObject(); if (Level == NULL) { TileDetails->StreamingLevels.Empty(); return; } // Delete all streaming levels from the world objects CastChecked<UWorld>(Level->GetOuter())->StreamingLevels.Empty(); // Recreate streaming levels using settings stored in the tile details for (auto It = TileDetails->StreamingLevels.CreateIterator(); It; ++It) { FTileStreamingLevelDetails& StreamingLevelDetails = (*It); FName PackageName = StreamingLevelDetails.PackageName; if (PackageName != NAME_None && FPackageName::DoesPackageExist(PackageName.ToString())) { UClass* StreamingClass = FTileStreamingLevelDetails::StreamingMode2Class(StreamingLevelDetails.StreamingMode); AddStreamingLevel(StreamingClass, PackageName); } } }
ENGINE_API bool BuildTextureStreamingData(UWorld* InWorld, const FTexCoordScaleMap& InTexCoordScales, EMaterialQualityLevel::Type QualityLevel, ERHIFeatureLevel::Type FeatureLevel, FSlowTask& BuildTextureStreamingTask) { #if WITH_EDITORONLY_DATA if (!InWorld) return false; const double StartTime = FPlatformTime::Seconds(); // ==================================================== // Build per primitive data // ==================================================== const float NumPrimitiveComponents = (float)GetNumTextureStreamingPrimitives(InWorld); FScopedSlowTask SlowTask(NumPrimitiveComponents, (LOCTEXT("TextureStreamingBuild_ComponentDataUpdate", "Updating Component Data"))); for (int32 LevelIndex = 0; LevelIndex < InWorld->GetNumLevels(); LevelIndex++) { ULevel* Level = InWorld->GetLevel(LevelIndex); if (!Level) continue; TArray<UTexture2D*> LevelTextures; TArray<UPrimitiveComponent*> Components; GetTextureStreamingPrimitives(Level, Components, false); for (UPrimitiveComponent* Primitive : Components) { // Update all primitives as this could clear unwanted data. Primitive->UpdateStreamingTextureData(LevelTextures, InTexCoordScales, QualityLevel, FeatureLevel); if (Primitive->RequiresStreamingTextureData()) { // Slow task only accounts for primitive having streaming data. SlowTask.EnterProgressFrame(); BuildTextureStreamingTask.EnterProgressFrame(1.f / NumPrimitiveComponents); if (GWarn->ReceivedUserCancel()) return false; UStaticMeshComponent* StaticMeshComponent = Cast<UStaticMeshComponent>(Primitive); if (StaticMeshComponent && StaticMeshComponent->StaticMesh && StaticMeshComponent->StaticMesh->GetLightingGuid().IsValid()) { // Add to the build Guids all used static meshes. Level->TextureStreamingBuildGuids.Add(StaticMeshComponent->StaticMesh->GetLightingGuid()); } } } // If a component was updated, or the level data needs reset. if (Level->bTextureStreamingRotationChanged || Level->StreamingTextureGuids.Num() || LevelTextures.Num()) { Level->bTextureStreamingRotationChanged = false; Level->StreamingTextureGuids.Empty(LevelTextures.Num()); Level->MarkPackageDirty(); // Reset LevelIndex to default for next use and build the level Guid array. for (int32 TextureIndex = 0; TextureIndex < LevelTextures.Num(); ++TextureIndex) { UTexture2D* Texture2D = LevelTextures[TextureIndex]; Level->StreamingTextureGuids.Push(Texture2D->GetLightingGuid()); Texture2D->LevelIndex = INDEX_NONE; } } } // ==================================================== // Update texture streaming data // ==================================================== ULevel::BuildStreamingData(InWorld); // ==================================================== // Reregister everything for debug view modes to reflect changes // ==================================================== for (int32 LevelIndex = 0; LevelIndex < InWorld->GetNumLevels(); LevelIndex++) { ULevel* Level = InWorld->GetLevel(LevelIndex); if (!Level) continue; for (AActor* Actor : Level->Actors) { if (!Actor) continue; Actor->MarkComponentsRenderStateDirty(); } } UE_LOG(TextureStreamingBuild, Display, TEXT("Build Texture Streaming took %.3f seconds."), FPlatformTime::Seconds() - StartTime); return true; #else UE_LOG(TextureStreamingBuild, Fatal,TEXT("Build Texture Streaming should not be called on a console")); return false; #endif }
bool FEditorBuildUtils::EditorAutomatedBuildAndSubmit( const FEditorAutomatedBuildSettings& BuildSettings, FText& OutErrorMessages ) { // Assume the build is successful to start bool bBuildSuccessful = true; // Keep a set of packages that should be submitted to source control at the end of a successful build. The build preparation and processing // will add and remove from the set depending on build settings, errors, etc. TSet<UPackage*> PackagesToSubmit; // Perform required preparations for the automated build process bBuildSuccessful = PrepForAutomatedBuild( BuildSettings, PackagesToSubmit, OutErrorMessages ); // If the preparation went smoothly, attempt the actual map building process if ( bBuildSuccessful ) { bBuildSuccessful = EditorBuild( GWorld, EBuildOptions::BuildAllSubmit ); // If the map build failed, log the error if ( !bBuildSuccessful ) { LogErrorMessage( NSLOCTEXT("UnrealEd", "AutomatedBuild_Error_BuildFailed", "The map build failed or was canceled."), OutErrorMessages ); } } // If any map errors resulted from the build, process them according to the behavior specified in the build settings if ( bBuildSuccessful && FMessageLog("MapCheck").NumMessages( EMessageSeverity::Warning ) > 0 ) { bBuildSuccessful = ProcessAutomatedBuildBehavior( BuildSettings.BuildErrorBehavior, NSLOCTEXT("UnrealEd", "AutomatedBuild_Error_MapErrors", "Map errors occurred while building.\n\nAttempt to continue the build?"), OutErrorMessages ); } // If it's still safe to proceed, attempt to save all of the level packages that have been marked for submission if ( bBuildSuccessful ) { UPackage* CurOutermostPkg = GWorld->PersistentLevel->GetOutermost(); FString PackagesThatFailedToSave; // Try to save the p-level if it should be submitted if ( PackagesToSubmit.Contains( CurOutermostPkg ) && !FEditorFileUtils::SaveLevel( GWorld->PersistentLevel ) ) { // If the p-level failed to save, remove it from the set of packages to submit PackagesThatFailedToSave += FString::Printf( TEXT("%s\n"), *CurOutermostPkg->GetName() ); PackagesToSubmit.Remove( CurOutermostPkg ); } // Try to save each streaming level (if they should be submitted) for ( TArray<ULevelStreaming*>::TIterator LevelIter( GWorld->StreamingLevels ); LevelIter; ++LevelIter ) { ULevelStreaming* CurStreamingLevel = *LevelIter; if ( CurStreamingLevel != NULL ) { ULevel* Level = CurStreamingLevel->GetLoadedLevel(); if ( Level != NULL ) { CurOutermostPkg = Level->GetOutermost(); if ( PackagesToSubmit.Contains( CurOutermostPkg ) && !FEditorFileUtils::SaveLevel( Level ) ) { // If a save failed, remove the streaming level from the set of packages to submit PackagesThatFailedToSave += FString::Printf( TEXT("%s\n"), *CurOutermostPkg->GetName() ); PackagesToSubmit.Remove( CurOutermostPkg ); } } } } // If any packages failed to save, process the behavior specified by the build settings to see how the process should proceed if ( PackagesThatFailedToSave.Len() > 0 ) { bBuildSuccessful = ProcessAutomatedBuildBehavior( BuildSettings.FailedToSaveBehavior, FText::Format( NSLOCTEXT("UnrealEd", "AutomatedBuild_Error_FilesFailedSave", "The following assets failed to save and cannot be submitted:\n\n{0}\n\nAttempt to continue the build?"), FText::FromString(PackagesThatFailedToSave) ), OutErrorMessages ); } } // If still safe to proceed, make sure there are actually packages remaining to submit if ( bBuildSuccessful ) { bBuildSuccessful = PackagesToSubmit.Num() > 0; if ( !bBuildSuccessful ) { LogErrorMessage( NSLOCTEXT("UnrealEd", "AutomatedBuild_Error_NoValidLevels", "None of the current levels are valid for submission; automated build aborted."), OutErrorMessages ); } } // Finally, if everything has gone smoothly, submit the requested packages to source control if ( bBuildSuccessful ) { SubmitPackagesForAutomatedBuild( PackagesToSubmit, BuildSettings ); } // Check if the user requested the editor shutdown at the conclusion of the automated build if ( BuildSettings.bShutdownEditorOnCompletion ) { FPlatformMisc::RequestExit( false ); } return bBuildSuccessful; }
void FShadowMapPendingTexture::StartEncoding(UWorld* InWorld) { // Create the shadow-map texture. UShadowMapTexture2D* Texture = new(Outer) UShadowMapTexture2D(FPostConstructInitializeProperties()); Texture->Filter = GUseBilinearLightmaps ? TF_Default : TF_Nearest; // Signed distance field textures get stored in linear space, since they need more precision near .5. Texture->SRGB = false; Texture->LODGroup = TEXTUREGROUP_Shadowmap; Texture->ShadowmapFlags = ShadowmapFlags; Texture->Source.Init2DWithMipChain(GetSizeX(), GetSizeY(), TSF_BGRA8); Texture->MipGenSettings = TMGS_LeaveExistingMips; Texture->CompressionNone = true; int32 TextureSizeX = Texture->Source.GetSizeX(); int32 TextureSizeY = Texture->Source.GetSizeY(); { // Create the uncompressed top mip-level. TArray< TArray<FFourDistanceFieldSamples> > MipData; FShadowMap2D::EncodeSingleTexture(*this, Texture, MipData); // Copy the mip-map data into the UShadowMapTexture2D's mip-map array. for(int32 MipIndex = 0;MipIndex < MipData.Num();MipIndex++) { FColor* DestMipData = (FColor*)Texture->Source.LockMip(MipIndex); uint32 MipSizeX = FMath::Max(1,TextureSizeX >> MipIndex); uint32 MipSizeY = FMath::Max(1,TextureSizeY >> MipIndex); for(uint32 Y = 0;Y < MipSizeY;Y++) { for(uint32 X = 0;X < MipSizeX;X++) { const FFourDistanceFieldSamples& SourceSample = MipData[MipIndex][Y * MipSizeX + X]; DestMipData[ Y * MipSizeX + X ] = FColor(SourceSample.Samples[0].Distance, SourceSample.Samples[1].Distance, SourceSample.Samples[2].Distance, SourceSample.Samples[3].Distance); } } Texture->Source.UnlockMip(MipIndex); } } // Update stats. int32 TextureSize = Texture->CalcTextureMemorySizeEnum( TMC_AllMips ); GNumShadowmapTotalTexels += TextureSizeX * TextureSizeY; GNumShadowmapTextures++; GShadowmapTotalSize += TextureSize; GShadowmapTotalStreamingSize += (ShadowmapFlags & SMF_Streamed) ? TextureSize : 0; UPackage* TexturePackage = Texture->GetOutermost(); for ( int32 LevelIndex=0; TexturePackage && LevelIndex < InWorld->GetNumLevels(); LevelIndex++ ) { ULevel* Level = InWorld->GetLevel(LevelIndex); UPackage* LevelPackage = Level->GetOutermost(); if ( TexturePackage == LevelPackage ) { Level->ShadowmapTotalSize += float(TextureSize) / 1024.0f; break; } } // Update the texture resource. Texture->BeginCachePlatformData(); Texture->FinishCachePlatformData(); Texture->UpdateResource(); }
void FLevelCollectionModel::SaveLevels(const FLevelModelList& InLevelList) { if (IsReadOnly()) { return; } FLevelModelList LevelModelsToSave; TArray<ULevel*> LevelsToSave; for (auto It = InLevelList.CreateConstIterator(); It; ++It) { if ((*It)->GetLevelObject()) { if (!(*It)->IsVisible()) { FMessageDialog::Open( EAppMsgType::Ok, NSLOCTEXT("UnrealEd", "UnableToSaveInvisibleLevels", "Save aborted. Levels must be made visible before they can be saved.") ); return; } else if ((*It)->IsLocked()) { FMessageDialog::Open( EAppMsgType::Ok, NSLOCTEXT("UnrealEd", "UnableToSaveLockedLevels", "Save aborted. Level must be unlocked before it can be saved.") ); return; } LevelModelsToSave.Add(*It); LevelsToSave.Add((*It)->GetLevelObject()); } } TArray< UPackage* > PackagesNotNeedingCheckout; // Prompt the user to check out the levels from source control before saving if (FEditorFileUtils::PromptToCheckoutLevels(false, LevelsToSave, &PackagesNotNeedingCheckout)) { for (auto It = LevelsToSave.CreateIterator(); It; ++It) { FEditorFileUtils::SaveLevel(*It); } } else if (PackagesNotNeedingCheckout.Num() > 0) { // The user canceled the checkout dialog but some packages didn't need to be checked out in order to save // For each selected level if the package its in didn't need to be saved, save the level! for (int32 LevelIdx = 0; LevelIdx < LevelsToSave.Num(); ++LevelIdx) { ULevel* Level = LevelsToSave[LevelIdx]; if (PackagesNotNeedingCheckout.Contains(Level->GetOutermost())) { FEditorFileUtils::SaveLevel(Level); } else { //remove it from the list, so that only successfully saved levels are highlighted when saving is complete LevelModelsToSave.RemoveAt(LevelIdx); LevelsToSave.RemoveAt(LevelIdx); } } } // Select tiles that were saved successfully SetSelectedLevels(LevelModelsToSave); }
/** This will set the StreamingLevels TMap with the current Streaming Level Status and also set which level the player is in **/ void GetLevelStreamingStatus( UWorld* World, TMap<FName,int32>& StreamingLevels, FString& LevelPlayerIsInName ) { FWorldContext &Context = GEngine->WorldContextFromWorld(World); // Iterate over the world info's level streaming objects to find and see whether levels are loaded, visible or neither. for( int32 LevelIndex=0; LevelIndex<World->StreamingLevels.Num(); LevelIndex++ ) { ULevelStreaming* LevelStreaming = World->StreamingLevels[LevelIndex]; if( LevelStreaming && LevelStreaming->PackageName != NAME_None && LevelStreaming->PackageName != World->GetOutermost()->GetFName() ) { ULevel* Level = LevelStreaming->GetLoadedLevel(); if( Level != NULL ) { if( World->ContainsLevel( Level ) == true ) { if( World->CurrentLevelPendingVisibility == Level ) { StreamingLevels.Add( LevelStreaming->PackageName, LEVEL_MakingVisible ); } else { StreamingLevels.Add( LevelStreaming->PackageName, LEVEL_Visible ); } } else { StreamingLevels.Add( LevelStreaming->PackageName, LEVEL_Loaded ); } } else { // See whether the level's world object is still around. UPackage* LevelPackage = Cast<UPackage>(StaticFindObjectFast( UPackage::StaticClass(), NULL, LevelStreaming->PackageName )); UWorld* LevelWorld = NULL; if( LevelPackage ) { LevelWorld = UWorld::FindWorldInPackage(LevelPackage); } if( LevelWorld ) { StreamingLevels.Add( LevelStreaming->PackageName, LEVEL_UnloadedButStillAround ); } else if( GetAsyncLoadPercentage( *LevelStreaming->PackageName.ToString() ) >= 0 ) { StreamingLevels.Add( LevelStreaming->PackageName, LEVEL_Loading ); } else { StreamingLevels.Add( LevelStreaming->PackageName, LEVEL_Unloaded ); } } } } // toss in the levels being loaded by PrepareMapChange for( int32 LevelIndex=0; LevelIndex < Context.LevelsToLoadForPendingMapChange.Num(); LevelIndex++ ) { const FName LevelName = Context.LevelsToLoadForPendingMapChange[LevelIndex]; StreamingLevels.Add(LevelName, LEVEL_Preloading); } ULevel* LevelPlayerIsIn = NULL; for( FConstPlayerControllerIterator Iterator = World->GetPlayerControllerIterator(); Iterator; ++Iterator ) { APlayerController* PlayerController = *Iterator; if( PlayerController->GetPawn() != NULL ) { // need to do a trace down here //TraceActor = Trace( out_HitLocation, out_HitNormal, TraceDest, TraceStart, false, TraceExtent, HitInfo, true ); FHitResult Hit(1.f); // this will not work for flying around :-( static FName NAME_FindLevel = FName(TEXT("FindLevel"), true); PlayerController->GetWorld()->LineTraceSingle(Hit,PlayerController->GetPawn()->GetActorLocation(), (PlayerController->GetPawn()->GetActorLocation()-FVector(0.f, 0.f, 256.f)), FCollisionQueryParams(NAME_FindLevel, true, PlayerController->GetPawn()), FCollisionObjectQueryParams(ECC_WorldStatic)); /** @todo UE4 FIXME if( Hit.Level != NULL ) { LevelPlayerIsIn = Hit.Level; } else */ if( Hit.GetActor() != NULL ) { LevelPlayerIsIn = Hit.GetActor()->GetLevel(); } else if( Hit.Component != NULL && Hit.Component->GetOwner() != NULL ) { AActor* Owner = Hit.Component->GetOwner(); if (Owner) { LevelPlayerIsIn = Owner->GetLevel(); } else { // This happens for BSP where the ModelComponent's outer is the level LevelPlayerIsIn = Hit.Component->GetTypedOuter<ULevel>(); } } } } // this no longer seems to be getting the correct level name :-( LevelPlayerIsInName = LevelPlayerIsIn != NULL ? LevelPlayerIsIn->GetOutermost()->GetName() : TEXT("None"); }
void FLevelCollectionModel::SCCDiffAgainstDepot(const FLevelModelList& InList, UEditorEngine* InEditor) { // Load the asset registry module FAssetToolsModule& AssetToolsModule = FModuleManager::GetModuleChecked<FAssetToolsModule>("AssetTools"); ISourceControlProvider& SourceControlProvider = ISourceControlModule::Get().GetProvider(); // Iterate over each selected asset for (auto It = InList.CreateConstIterator(); It; ++It) { ULevel* Level = (*It)->GetLevelObject(); if (Level == NULL) { return; } UPackage* OriginalPackage = Level->GetOutermost(); FString PackageName = OriginalPackage->GetName(); // Make sure our history is up to date auto UpdateStatusOperation = ISourceControlOperation::Create<FUpdateStatus>(); UpdateStatusOperation->SetUpdateHistory(true); SourceControlProvider.Execute(UpdateStatusOperation, OriginalPackage); // Get the SCC state FSourceControlStatePtr SourceControlState = SourceControlProvider.GetState( OriginalPackage, EStateCacheUsage::Use ); // If the level is in SCC. if (SourceControlState.IsValid() && SourceControlState->IsSourceControlled()) { // Get the file name of package FString RelativeFileName; if(FPackageName::DoesPackageExist(PackageName, NULL, &RelativeFileName)) { if (SourceControlState->GetHistorySize() > 0) { auto Revision = SourceControlState->GetHistoryItem(0); check(Revision.IsValid()); // Get the head revision of this package from source control FString AbsoluteFileName = FPaths::ConvertRelativePathToFull(RelativeFileName); FString TempFileName; if (Revision->Get(TempFileName)) { // Forcibly disable compile on load in case we are loading old blueprints that might try to update/compile TGuardValue<bool> DisableCompileOnLoad(GForceDisableBlueprintCompileOnLoad, true); // Try and load that package FText NotMapReason; UPackage* OldPackage = LoadPackage(NULL, *TempFileName, LOAD_None); if(OldPackage != NULL && InEditor->PackageIsAMapFile(*TempFileName, NotMapReason)) { /* Set the revision information*/ UPackage* Package = OriginalPackage; FRevisionInfo OldRevision; OldRevision.Changelist = Revision->GetCheckInIdentifier(); OldRevision.Date = Revision->GetDate(); OldRevision.Revision = Revision->GetRevision(); FRevisionInfo NewRevision; NewRevision.Revision = TEXT(""); // Dump assets to temp text files FString OldTextFilename = AssetToolsModule.Get().DumpAssetToTempFile(OldPackage); FString NewTextFilename = AssetToolsModule.Get().DumpAssetToTempFile(OriginalPackage); FString DiffCommand = GetDefault<UEditorLoadingSavingSettings>()->TextDiffToolPath.FilePath; AssetToolsModule.Get().CreateDiffProcess(DiffCommand, OldTextFilename, NewTextFilename); AssetToolsModule.Get().DiffAssets(OldPackage, OriginalPackage, OldRevision, NewRevision); } } } } } } }
/** Clears and optionally backs up all references to renderer module classes in other modules, particularly engine. */ void ClearReferencesToRendererModuleClasses( TMap<UWorld*, bool>& WorldsToUpdate, TMap<FMaterialShaderMap*, TScopedPointer<TArray<uint8> > >& ShaderMapToSerializedShaderData, TScopedPointer<TArray<uint8> >& GlobalShaderData, TMap<FShaderType*, FString>& ShaderTypeNames, TMap<FVertexFactoryType*, FString>& VertexFactoryTypeNames) { // Destroy all renderer scenes for (TObjectIterator<UWorld> WorldIt; WorldIt; ++WorldIt) { UWorld* World = *WorldIt; if (World->Scene) { WorldsToUpdate.Add(World, World->FXSystem != NULL); for (int32 LevelIndex = 0; LevelIndex < World->GetNumLevels(); LevelIndex++) { ULevel* Level = World->GetLevel(LevelIndex); Level->ReleaseRenderingResources(); } if (World->FXSystem != NULL) { FFXSystemInterface::Destroy(World->FXSystem); World->FXSystem = NULL; } World->Scene->Release(); World->Scene = NULL; } } // Save off shaders by serializing them into memory, and remove all shader map references to FShaders GlobalShaderData = TScopedPointer<TArray<uint8> >(BackupGlobalShaderMap(GRHIShaderPlatform_DEPRECATED)); UMaterial::BackupMaterialShadersToMemory(ShaderMapToSerializedShaderData); // Verify no FShaders still in memory for(TLinkedList<FShaderType*>::TIterator It(FShaderType::GetTypeList()); It; It.Next()) { FShaderType* ShaderType = *It; check(ShaderType->GetNumShaders() == 0); ShaderTypeNames.Add(ShaderType, ShaderType->GetName()); } for(TLinkedList<FVertexFactoryType*>::TIterator It(FVertexFactoryType::GetTypeList()); It; It.Next()) { FVertexFactoryType* VertexFactoryType = *It; VertexFactoryTypeNames.Add(VertexFactoryType, VertexFactoryType->GetName()); } // Destroy misc renderer module classes and remove references FSceneViewStateReference::DestroyAll(); FSlateApplication::Get().InvalidateAllViewports(); // Invalidate cached shader type data UninitializeShaderTypes(); // Delete pending cleanup objects to remove those references, which are potentially renderer module classes FPendingCleanupObjects* PendingCleanupObjects = GetPendingCleanupObjects(); delete PendingCleanupObjects; GEngine->EngineLoop->ClearPendingCleanupObjects(); ResetCachedRendererModule(); }