ShowFlag.BSP

ShowFlag.BSP

#Overview

name: ShowFlag.BSP

This variable is created as a Console Variable (cvar).

It is referenced in 14 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of ShowFlag.BSP is to control the visibility of Binary Space Partitioning (BSP) geometry in the Unreal Engine rendering system. BSP is a method used for spatial partitioning and is primarily associated with level geometry and brush-based actors.

This setting variable is primarily used in the rendering and editor subsystems of Unreal Engine. Based on the callsites, it’s utilized in the following areas:

  1. Level Editor viewport rendering
  2. Actor positioning and selection in the editor
  3. Brush component visibility
  4. Model scene proxy rendering

The value of this variable is typically set through the engine’s show flags system, which allows toggling various rendering features on and off. It can be modified through the engine’s user interface or programmatically.

Several other variables interact with ShowFlag.BSP:

  1. EngineShowFlags.BSPTriangles: Controls the rendering of BSP triangles
  2. EngineShowFlags.Brushes: Affects the visibility of brush actors
  3. EngineShowFlags.BuilderBrush: Specifically for the visibility of the builder brush

Developers should be aware of the following when using this variable:

  1. It affects both editor and game viewports
  2. It can impact performance, especially in scenes with complex BSP geometry
  3. It’s often used in conjunction with other show flags for full control over scene visualization

Best practices when using this variable include:

  1. Use it judiciously in game builds, as BSP visibility might not be necessary for players
  2. Consider performance implications when enabling BSP rendering in complex scenes
  3. Combine it with other show flags for more granular control over scene visualization

Regarding the associated variable “BSP”, it appears to be used in similar contexts as ShowFlag.BSP, particularly in editor-related code. It’s used for similar purposes, such as controlling BSP visibility and selection in the editor. The same considerations and best practices apply to this variable as well.

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/ShowFlagsValues.inl:285

Scope: file

Source code excerpt:

SHOWFLAG_FIXED_IN_SHIPPING(0, ActorColoration, SFG_Transient, NSLOCTEXT("UnrealEd", "ActorColorationSF", "Actor Coloration"))
/** Draws BSP brushes (in game or editor textured triangles usually with lightmaps), for now SHOWFLAG_ALWAYS_ACCESSIBLE because it's exposed in SceneCapture */
SHOWFLAG_ALWAYS_ACCESSIBLE(BSP, SFG_Normal, NSLOCTEXT("UnrealEd", "BSPSF", "BSP"))
/** Collision drawing */
SHOWFLAG_FIXED_IN_SHIPPING(0, Collision, SFG_Normal, NSLOCTEXT("UnrealEd", "CollisionWireFrame", "Collision"))
/** Collision blocking visibility against complex **/
SHOWFLAG_FIXED_IN_SHIPPING(0, CollisionVisibility, SFG_Hidden, NSLOCTEXT("UnrealEd", "CollisionVisibility", "Visibility"))
/** Collision blocking pawn against simple collision **/
SHOWFLAG_FIXED_IN_SHIPPING(0, CollisionPawn, SFG_Hidden, NSLOCTEXT("UnrealEd", "CollisionPawn", "Pawn"))

#Associated Variable and Callsites

This variable is associated with another variable named BSP. They share the same value. See the following C++ source code.

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/DragTool_BoxSelect.cpp:71

Scope (from outer to inner):

file
function     void FDragTool_ActorBoxSelect::StartDrag

Source code excerpt:

	FLevelEditorViewportClient::ClearHoverFromObjects();

	// Create a list of bsp models to check for intersection with the box
	ModelsToCheck.Reset();
	// Do not select BSP if its not visible
	if( InViewportClient->EngineShowFlags.BSP)
	{
		UWorld* World = InViewportClient->GetWorld();
		check(World);
		// Add the persistent level always
		ModelsToCheck.Add( World->PersistentLevel->Model );
		// Add all streaming level models
		for (ULevelStreaming* StreamingLevel : World->GetStreamingLevels())
		{
			// Only add streaming level models if the level is visible
			if (StreamingLevel && StreamingLevel->GetShouldBeVisibleInEditor())
			{	

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Editor/ActorPositioning.cpp:135

Scope (from outer to inner):

file
function     bool IsHitIgnoredRenderingThread

Source code excerpt:

		const bool bConsiderInvisibleComponentForPlacement = PrimitiveComponent->bConsiderForActorPlacementWhenHidden;

		// Only use this component if it is visible in the specified scene views
		const FPrimitiveViewRelevance ViewRelevance = PrimitiveComponent->SceneProxy->GetViewRelevance(&InSceneView);
		// BSP is a bit special in that its bDrawRelevance is false even when drawn as wireframe because InSceneView.Family->EngineShowFlags.BSPTriangles is off
		const bool bIsRenderedOnScreen = ViewRelevance.bDrawRelevance || (PrimitiveComponent->IsA(UModelComponent::StaticClass()) && InSceneView.Family->EngineShowFlags.BSP);
		const bool bIgnoreTranslucentPrimitive = ViewRelevance.HasTranslucency() && !GetDefault<UEditorPerProjectUserSettings>()->bAllowSelectTranslucent;
		
		return (!bIsRenderedOnScreen && !bConsiderInvisibleComponentForPlacement) || bIgnoreTranslucentPrimitive;
	}

	return false;
}

FActorPositionTraceResult FActorPositioning::TraceWorldForPosition(const UWorld& InWorld, const FSceneView& InSceneView, const FVector& RayStart, const FVector& RayEnd, const TArray<AActor*>* IgnoreActors)
{
	TArray<FHitResult> Hits;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/EditorModeManager.cpp:1596

Scope (from outer to inner):

file
function     void FEditorModeTools::DrawHUD

Source code excerpt:

		return;
	}

	// Temporaries.
	const bool bShowBrushes = View->Family->EngineShowFlags.Brushes;
	const bool bShowBSP = View->Family->EngineShowFlags.BSP;
	const bool bShowBuilderBrush = View->Family->EngineShowFlags.BuilderBrush != 0;

	UTexture2D* VertexTexture = GetVertexTexture();
	const float TextureSizeX = VertexTexture->GetSizeX() * (bLargeVertices ? 1.0f : 0.5f);
	const float TextureSizeY = VertexTexture->GetSizeY() * (bLargeVertices ? 1.0f : 0.5f);

	GetEditorSelectionSet()->ForEachSelectedObject<AStaticMeshActor>([View, Canvas, VertexTexture, TextureSizeX, TextureSizeY, bIsHitTesting](AStaticMeshActor* Actor)
		{
			TArray<FVector> Vertices;
			FCanvasItemTestbed::bTestState = !FCanvasItemTestbed::bTestState;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/EditorServer.cpp:5601

Scope (from outer to inner):

file
function     bool UEditorEngine::Exec_Editor

Source code excerpt:

		}
	}
	//------------------------------------------------------------------------------------
	// BSP
	//
	else if( FParse::Command( &Str, TEXT("BSP") ) )
	{
		return CommandIsDeprecated( *CommandTemp, Ar );
	}
	//------------------------------------------------------------------------------------
	// LIGHT
	//
	else if( FParse::Command( &Str, TEXT("LIGHT") ) )
	{
		return CommandIsDeprecated( *CommandTemp, Ar );
	}
	//------------------------------------------------------------------------------------

#Loc: <Workspace>/Engine/Source/Runtime/Core/Public/UObject/UnrealNames.inl:187

Scope: file

Source code excerpt:

REGISTER_NAME(245,GameThread)
REGISTER_NAME(246,RenderThread)
REGISTER_NAME(247,OtherChildren)
REGISTER_NAME(248,Location)
REGISTER_NAME(249,Rotation)
REGISTER_NAME(250,BSP)
REGISTER_NAME(251,EditorSettings)
REGISTER_NAME(252,AudioThread)
REGISTER_NAME(253,ID)
REGISTER_NAME(254,UserDefinedEnum)
REGISTER_NAME(255,Control)
REGISTER_NAME(256,Voice)
REGISTER_NAME(257, Zlib)
REGISTER_NAME(258, Gzip)
REGISTER_NAME(259, LZ4)
REGISTER_NAME(260, Mobile)
REGISTER_NAME(261, Oodle)

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/BrushComponent.cpp:315

Scope (from outer to inner):

file
class        class FBrushSceneProxy final : public FPrimitiveSceneProxy
function     virtual FPrimitiveViewRelevance GetViewRelevance

Source code excerpt:

				}
			}

			if(bNeverShow == false)
			{
				const bool bBSPVisible = View->Family->EngineShowFlags.BSP;
				const bool bBrushesVisible = View->Family->EngineShowFlags.Brushes;

				if ( !bVolume ) // EngineShowFlags.Collision does not apply to volumes
				{
					if( (bBSPVisible && bBrushesVisible) )
					{
						bVisible = true;
					}
				}

				// See if we should be visible because we are in a 'collision view' and have collision enabled

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/BrushComponent.cpp:530

Scope (from outer to inner):

file
function     bool UBrushComponent::IsShown

Source code excerpt:


bool UBrushComponent::IsShown(const FEngineShowFlags& ShowFlags) const
{
	if (const AActor* Actor = GetOwner())
	{
		return (Actor->IsA(AVolume::StaticClass())) ? ShowFlags.Volumes : ShowFlags.BSP;
	}

	return false;
}

#if WITH_EDITOR
bool UBrushComponent::ComponentIsTouchingSelectionBox(const FBox& InSelBBox, const bool bConsiderOnlyBSP, const bool bMustEncompassEntireComponent) const
{
	if (Brush != nullptr && Brush->Polys != nullptr)
	{
		TArray<FVector> Vertices;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/ModelRender.cpp:303

Scope (from outer to inner):

file
class        class FModelSceneProxy final : public FPrimitiveSceneProxy
function     virtual void GetDynamicMeshElements

Source code excerpt:

				const FSceneView* View = Views[ViewIndex];

				bool bShowSelection = GIsEditor && !View->bIsGameView && ViewFamily.EngineShowFlags.Selection;
				bool bDynamicBSPTriangles = bShowSelection || IsRichView(ViewFamily);
				bool bShowBSPTriangles = ViewFamily.EngineShowFlags.BSPTriangles;
				bool bShowBSP = ViewFamily.EngineShowFlags.BSP;

#if WITH_EDITOR
				bool bDrawCollision = false;
				const bool bInCollisionView = IsCollisionView(View, bDrawCollision);
				// draw bsp as dynamic when in collision view mode
				if(bInCollisionView)
				{
					bDynamicBSPTriangles = true;
				}
#endif

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/ModelRender.cpp:536

Scope (from outer to inner):

file
class        class FModelSceneProxy final : public FPrimitiveSceneProxy
function     virtual FPrimitiveViewRelevance GetViewRelevance

Source code excerpt:

	}

	virtual FPrimitiveViewRelevance GetViewRelevance(const FSceneView* View) const override
	{
		FPrimitiveViewRelevance Result;
		Result.bDrawRelevance = IsShown(View) && View->Family->EngineShowFlags.BSPTriangles && View->Family->EngineShowFlags.BSP;
		bool bShowSelectedTriangles = GIsEditor && !View->bIsGameView && View->Family->EngineShowFlags.Selection;
		bool bCollisionView = View->Family->EngineShowFlags.CollisionPawn || View->Family->EngineShowFlags.CollisionVisibility;
		if (IsRichView(*View->Family) || HasViewDependentDPG() || bCollisionView
			|| (bShowSelectedTriangles && HasSelectedSurfaces()))
		{
			Result.bDynamicRelevance = true;
		}
		else
		{
			Result.bStaticRelevance = true;
		}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/ShowFlags.cpp:654

Scope (from outer to inner):

file
function     void EngineShowFlagOverride

Source code excerpt:

			 DISABLE_ENGINE_SHOWFLAG(TextRender)
			 DISABLE_ENGINE_SHOWFLAG(Particles)
			 DISABLE_ENGINE_SHOWFLAG(SkeletalMeshes)
			 DISABLE_ENGINE_SHOWFLAG(StaticMeshes)
			 DISABLE_ENGINE_SHOWFLAG(NaniteMeshes)
			 DISABLE_ENGINE_SHOWFLAG(BSP)
			 DISABLE_ENGINE_SHOWFLAG(Paper2DSprites)
#undef DISABLE_ENGINE_SHOWFLAG
		}
	}
#endif

	// Force some show flags to be 0 or 1
	{
		const uint8* Force0Ptr = (const uint8*)&GSystemSettings.GetForce0Mask();
		const uint8* Force1Ptr = (const uint8*)&GSystemSettings.GetForce1Mask();
		uint8* Ptr = (uint8*)&EngineShowFlags;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/ShowFlagsValues.inl:282

Scope: file

Source code excerpt:

/** if this is a game viewport, needed? */
SHOWFLAG_ALWAYS_ACCESSIBLE(Game, SFG_Hidden, NSLOCTEXT("UnrealEd", "GameSF", "Game"))
/** Render objects with colors based on what the actors coloring handlers provides */
SHOWFLAG_FIXED_IN_SHIPPING(0, ActorColoration, SFG_Transient, NSLOCTEXT("UnrealEd", "ActorColorationSF", "Actor Coloration"))
/** Draws BSP brushes (in game or editor textured triangles usually with lightmaps), for now SHOWFLAG_ALWAYS_ACCESSIBLE because it's exposed in SceneCapture */
SHOWFLAG_ALWAYS_ACCESSIBLE(BSP, SFG_Normal, NSLOCTEXT("UnrealEd", "BSPSF", "BSP"))
/** Collision drawing */
SHOWFLAG_FIXED_IN_SHIPPING(0, Collision, SFG_Normal, NSLOCTEXT("UnrealEd", "CollisionWireFrame", "Collision"))
/** Collision blocking visibility against complex **/
SHOWFLAG_FIXED_IN_SHIPPING(0, CollisionVisibility, SFG_Hidden, NSLOCTEXT("UnrealEd", "CollisionVisibility", "Visibility"))
/** Collision blocking pawn against simple collision **/
SHOWFLAG_FIXED_IN_SHIPPING(0, CollisionPawn, SFG_Hidden, NSLOCTEXT("UnrealEd", "CollisionPawn", "Pawn"))
/** Render LightShafts, for now SHOWFLAG_ALWAYS_ACCESSIBLE because it's exposed in SceneCapture */
SHOWFLAG_ALWAYS_ACCESSIBLE(LightShafts, SFG_LightingFeatures, NSLOCTEXT("UnrealEd", "LightShaftsSF", "Light Shafts"))
/** Render the PostProcess Material */
SHOWFLAG_FIXED_IN_SHIPPING(1, PostProcessMaterial, SFG_PostProcess, NSLOCTEXT("UnrealEd", "PostProcessMaterialSF", "Post Process Material"))
/** Render Sky and Atmospheric lighting, for now SHOWFLAG_ALWAYS_ACCESSIBLE because it's exposed in SceneCapture */

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/SceneHitProxyRendering.cpp:1019

Scope (from outer to inner):

file
function     int32 FEditorSelectionMeshProcessor::GetStencilValue

Source code excerpt:


	// Reserved values for the stencil buffer that carry specific meaning
	enum ESelectionStencilValues : int32
	{
		NotSelected = 0,
		BSP = 1, // The outlines of all BSPs should be merged

		COUNT,
	};

	static constexpr int BitsAvailable = 8; // Stencil buffer is 8-bit
	static constexpr int ColorBits = 3; // Can be changed
	static constexpr int UniqueIdBits = BitsAvailable - ColorBits;
	static constexpr int MaxColor = (1 << ColorBits);
	static constexpr int MaxUniqueId = (1 << UniqueIdBits);
	
	auto EncodeSelectionStencilValue = [](int32 ColorIndex, int32 UniqueId) -> int32

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/SceneHitProxyRendering.cpp:1053

Scope (from outer to inner):

file
function     int32 FEditorSelectionMeshProcessor::GetStencilValue

Source code excerpt:

	
	int32 StencilValue = ESelectionStencilValues::NotSelected;

	if (PrimitiveSceneProxy->GetOwnerName() == NAME_BSP)
	{
		StencilValue = ESelectionStencilValues::BSP;
	}
	else if (ExistingStencilValue != nullptr)
	{
		StencilValue = *ExistingStencilValue;
	}
	else if (PrimitiveSceneProxy->IsIndividuallySelected())
	{
		const int Color = 0;
		const int UniqueId = ProxyToStencilIndex.Num();
		StencilValue = EncodeSelectionStencilValue(Color, UniqueId);
		ProxyToStencilIndex.Add(PrimitiveSceneProxy, StencilValue);