Exemple #1
0
void FLayers::AppendActorsForLayer( const FName& LayerName, TArray< TWeakObjectPtr< AActor > >& InActors, const TSharedPtr< ActorFilter >& Filter ) const
{
	for( FActorIterator ActorIt(GetWorld()); ActorIt; ++ActorIt ) 
	{
		const TWeakObjectPtr< AActor > Actor = *ActorIt;

		if( Filter.IsValid() && !Filter->PassesFilter( Actor ))
		{
			continue;
		}

		if( Actor->Layers.Contains( LayerName ) )
		{
			InActors.Add( Actor );
		}
	}
}
UEditorActorFolders& FActorFolders::InitializeForWorld(UWorld& InWorld)
{
	// Clean up any stale worlds
	Housekeeping();

	// We intentionally don't pass RF_Transactional to ConstructObject so that we don't record the creation of the object into the undo buffer
	// (to stop it getting deleted on undo as we manage its lifetime), but we still want it to be RF_Transactional so we can record any changes later
	UEditorActorFolders* Folders = NewObject<UEditorActorFolders>(GetTransientPackage(), NAME_None, RF_NoFlags);
	Folders->SetFlags(RF_Transactional);
	TemporaryWorldFolders.Add(&InWorld, Folders);

	// Ensure the list is entirely up to date with the world before we write our serialized properties into it.
	for (FActorIterator ActorIt(&InWorld); ActorIt; ++ActorIt)
	{
		AddFolderToWorld(InWorld, ActorIt->GetFolderPath());
	}

	// Attempt to load the folder properties from this user's saved world state directory
	const auto Filename = GetWorldStateFilename(InWorld.GetOutermost());
	TUniquePtr<FArchive> Ar(IFileManager::Get().CreateFileReader(*Filename));
	if (Ar)
	{
		TSharedPtr<FJsonObject> RootObject = MakeShareable(new FJsonObject);

		auto Reader = TJsonReaderFactory<TCHAR>::Create(Ar.Get());
		if (FJsonSerializer::Deserialize(Reader, RootObject))
		{
			const TSharedPtr<FJsonObject>& JsonFolders = RootObject->GetObjectField(TEXT("Folders"));
			for (const auto& KeyValue : JsonFolders->Values)
			{
				// Only pull in the folder's properties if this folder still exists in the world.
				// This means that old stale folders won't re-appear in the world (they'll won't get serialized when the world is saved anyway)
				if (FActorFolderProps* FolderInWorld = Folders->Folders.Find(*KeyValue.Key))
				{
					auto FolderProperties = KeyValue.Value->AsObject();
					FolderInWorld->bIsExpanded = FolderProperties->GetBoolField(TEXT("bIsExpanded"));
				}
			}
		}
		Ar->Close();
	}

	return *Folders;
}
void FActorFolders::RebuildFolderListForWorld(UWorld& InWorld)
{
	if (TemporaryWorldFolders.Contains(&InWorld))
	{
		// We don't empty the existing folders so that we keep empty ones.
		// Explicitly deleted folders will already be removed from the list

		// Iterate over every actor in memory. WARNING: This is potentially very expensive!
		for (FActorIterator ActorIt(&InWorld); ActorIt; ++ActorIt)
		{
			AddFolderToWorld(InWorld, ActorIt->GetFolderPath());
		}
	}
	else
	{
		// No folders exist for this world yet - creating them will ensure they're up to date
		InitializeForWorld(InWorld);
	}
}
void UGameEngine::PreExit()
{
	FAVIWriter* AVIWriter = FAVIWriter::GetInstance();
	if (AVIWriter)
	{
		AVIWriter->Close();
	}

	Super::PreExit();

	// Stop tracking, automatically flushes.
	NETWORK_PROFILER(GNetworkProfiler.EnableTracking(false));

	CancelAllPending();

	// Clean up all worlds
	for (int32 WorldIndex = 0; WorldIndex < WorldList.Num(); ++WorldIndex)
	{
		UWorld* const World = WorldList[WorldIndex].World();
		if ( World != NULL )
		{
			World->bIsTearingDown = true;

			// Cancel any pending connection to a server
			CancelPending(World);

			// Shut down any existing game connections
			ShutdownWorldNetDriver(World);

			for (FActorIterator ActorIt(World); ActorIt; ++ActorIt)
			{
				ActorIt->RouteEndPlay(EEndPlayReason::Quit);
			}

			World->GetGameInstance()->Shutdown();

			World->FlushLevelStreaming(EFlushLevelStreamingType::Visibility);
			World->CleanupWorld();
		}
	}
}
Exemple #5
0
void FLayers::AppendActorsForLayers( const TArray< FName >& LayerNames, TArray< TWeakObjectPtr< AActor > >& OutActors, const TSharedPtr< ActorFilter >& Filter ) const
{
	for( FActorIterator ActorIt(GetWorld()); ActorIt; ++ActorIt )
	{
		const TWeakObjectPtr< AActor > Actor = *ActorIt;

		if( Filter.IsValid() && !Filter->PassesFilter( Actor ))
		{
			continue;
		}

		for( auto LayerNameIt = LayerNames.CreateConstIterator(); LayerNameIt; ++LayerNameIt )
		{
			const FName& LayerName = *LayerNameIt;

			if( Actor->Layers.Contains( LayerName ) )
			{
				OutActors.Add( Actor );
				break;
			}
		}
	}
}
void FRCPassPostProcessSelectionOutlineColor::Process(FRenderingCompositePassContext& Context)
{
	SCOPED_DRAW_EVENT(Context.RHICmdList, PostProcessSelectionOutlineBuffer, DEC_SCENE_ITEMS);

	const FPooledRenderTargetDesc* SceneColorInputDesc = GetInputDesc(ePId_Input0);

	if(!SceneColorInputDesc)
	{
		// input is not hooked up correctly
		return;
	}

	const FViewInfo& View = Context.View;
	FIntRect ViewRect = View.ViewRect;
	FIntPoint SrcSize = SceneColorInputDesc->Extent;

	// Get the output render target
	const FSceneRenderTargetItem& DestRenderTarget = PassOutputs[0].RequestSurface(Context);
	
	// Set the render target/viewport.
	SetRenderTarget(Context.RHICmdList, FTextureRHIParamRef(), DestRenderTarget.TargetableTexture);
	// This is a reversed Z depth surface, so 0.0f is the far plane.
	Context.RHICmdList.Clear(false, FLinearColor(0, 0, 0, 0), true, 0.0f, true, 0, FIntRect());
	Context.SetViewportAndCallRHI(ViewRect);

	if (View.Family->EngineShowFlags.Selection)
	{
		const bool bUseGetMeshElements = ShouldUseGetDynamicMeshElements();

		if (bUseGetMeshElements)
		{
			FHitProxyDrawingPolicyFactory::ContextType FactoryContext;

			//@todo - use memstack
			TMap<FName, int32> ActorNameToStencilIndex;
			ActorNameToStencilIndex.Add(NAME_BSP, 1);

			Context.RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI());
			Context.RHICmdList.SetBlendState(TStaticBlendStateWriteMask<CW_NONE, CW_NONE, CW_NONE, CW_NONE>::GetRHI());

			for (int32 MeshBatchIndex = 0; MeshBatchIndex < View.DynamicMeshElements.Num(); MeshBatchIndex++)
			{
				const FMeshBatchAndRelevance& MeshBatchAndRelevance = View.DynamicMeshElements[MeshBatchIndex];
				const FPrimitiveSceneProxy* PrimitiveSceneProxy = MeshBatchAndRelevance.PrimitiveSceneProxy;

				if (PrimitiveSceneProxy->IsSelected() && MeshBatchAndRelevance.Mesh->bUseSelectionOutline)
				{
					const int32* AssignedStencilIndexPtr = ActorNameToStencilIndex.Find(PrimitiveSceneProxy->GetOwnerName());

					if (!AssignedStencilIndexPtr)
					{
						AssignedStencilIndexPtr = &ActorNameToStencilIndex.Add(PrimitiveSceneProxy->GetOwnerName(), ActorNameToStencilIndex.Num() + 1);
					}

					// This is a reversed Z depth surface, using CF_GreaterEqual.
					// Note that the stencil value will overflow with enough selected objects
					Context.RHICmdList.SetDepthStencilState(TStaticDepthStencilState<true, CF_GreaterEqual, true, CF_Always, SO_Keep, SO_Keep, SO_Replace>::GetRHI(), *AssignedStencilIndexPtr);

					const FMeshBatch& MeshBatch = *MeshBatchAndRelevance.Mesh;
					FHitProxyDrawingPolicyFactory::DrawDynamicMesh(Context.RHICmdList, View, FactoryContext, MeshBatch, false, true, MeshBatchAndRelevance.PrimitiveSceneProxy, MeshBatch.BatchHitProxyId);
				}
			}
		}
		else if (View.VisibleDynamicPrimitives.Num() > 0)
		{
			TDynamicPrimitiveDrawer<FHitProxyDrawingPolicyFactory> Drawer(Context.RHICmdList, &View, FHitProxyDrawingPolicyFactory::ContextType(), true, false, false, true);
			TMultiMap<FName, const FPrimitiveSceneInfo*> PrimitivesByActor;

			for (int32 PrimitiveIndex = 0; PrimitiveIndex < View.VisibleDynamicPrimitives.Num();PrimitiveIndex++)
			{
				const FPrimitiveSceneInfo* PrimitiveSceneInfo = View.VisibleDynamicPrimitives[PrimitiveIndex];

				// Only draw the primitive if relevant
				if(PrimitiveSceneInfo->Proxy->IsSelected())
				{
					PrimitivesByActor.Add(PrimitiveSceneInfo->Proxy->GetOwnerName(), PrimitiveSceneInfo);
				}
			}

			if (PrimitivesByActor.Num())
			{
				// 0 means no object, 1 means BSP so we start with 2
				uint32 StencilValue = 2;

				Context.RHICmdList.SetRasterizerState(TStaticRasterizerState<>::GetRHI());
				Context.RHICmdList.SetBlendState(TStaticBlendStateWriteMask<CW_NONE, CW_NONE, CW_NONE, CW_NONE>::GetRHI());

				// Sort by actor
				TArray<FName> Actors;
				PrimitivesByActor.GetKeys(Actors);
				for( TArray<FName>::TConstIterator ActorIt(Actors); ActorIt; ++ActorIt )
				{
					bool bBSP = *ActorIt == NAME_BSP;
					if (bBSP)
					{
						// This is a reversed Z depth surface, using CF_GreaterEqual.
						Context.RHICmdList.SetDepthStencilState(TStaticDepthStencilState<true, CF_GreaterEqual, true, CF_Always, SO_Keep, SO_Keep, SO_Replace>::GetRHI(), 1);
					}
					else
					{
						// This is a reversed Z depth surface, using CF_GreaterEqual.
						Context.RHICmdList.SetDepthStencilState(TStaticDepthStencilState<true, CF_GreaterEqual, true, CF_Always, SO_Keep, SO_Keep, SO_Replace>::GetRHI(), StencilValue);

						// we want to use 1..255 for all objects, not correct silhouettes after that is acceptable
						StencilValue = (StencilValue == 255) ? 2 : (StencilValue + 1);
					}

					TArray<const FPrimitiveSceneInfo*> Primitives;
					PrimitivesByActor.MultiFind(*ActorIt, Primitives);

					for( TArray<const FPrimitiveSceneInfo*>::TConstIterator PrimIt(Primitives); PrimIt; ++PrimIt )
					{
						const FPrimitiveSceneInfo* PrimitiveSceneInfo = *PrimIt;
						// Render the object to the stencil/depth buffer
						Drawer.SetPrimitive(PrimitiveSceneInfo->Proxy);
						PrimitiveSceneInfo->Proxy->DrawDynamicElements(&Drawer, &View);
					}
				}
			}
		}

		// to get an outline around the objects if it's partly outside of the screen
		{
			FIntRect InnerRect = ViewRect;

			// 1 as we have an outline that is that thick
			InnerRect.InflateRect(-1);

			// We could use Clear with InnerRect but this is just an optimization - on some hardware it might do a full clear (and we cannot disable yet)
			//			RHICmdList.Clear(false, FLinearColor(0, 0, 0, 0), true, 0.0f, true, 0, InnerRect);
			// so we to 4 clears - one for each border.

			// top
			Context.RHICmdList.SetScissorRect(true, ViewRect.Min.X, ViewRect.Min.Y, ViewRect.Max.X, InnerRect.Min.Y);
			Context.RHICmdList.Clear(false, FLinearColor(0, 0, 0, 0), true, 0.0f, true, 0, FIntRect());
			// bottom
			Context.RHICmdList.SetScissorRect(true, ViewRect.Min.X, InnerRect.Max.Y, ViewRect.Max.X, ViewRect.Max.Y);
			Context.RHICmdList.Clear(false, FLinearColor(0, 0, 0, 0), true, 0.0f, true, 0, FIntRect());
			// left
			Context.RHICmdList.SetScissorRect(true, ViewRect.Min.X, ViewRect.Min.Y, InnerRect.Min.X, ViewRect.Max.Y);
			Context.RHICmdList.Clear(false, FLinearColor(0, 0, 0, 0), true, 0.0f, true, 0, FIntRect());
			// right
			Context.RHICmdList.SetScissorRect(true, InnerRect.Max.X, ViewRect.Min.Y, ViewRect.Max.X, ViewRect.Max.Y);
			Context.RHICmdList.Clear(false, FLinearColor(0, 0, 0, 0), true, 0.0f, true, 0, FIntRect());

			Context.RHICmdList.SetScissorRect(false, 0, 0, 0, 0);
		}
	}
	
	// Resolve to the output
	Context.RHICmdList.CopyToResolveTarget(DestRenderTarget.TargetableTexture, DestRenderTarget.ShaderResourceTexture, false, FResolveParams());
}