void FTangoPointCloudSceneProxy::GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily & ViewFamily, uint32 VisibilityMap, FMeshElementCollector & Collector) const { for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { if (VisibilityMap & (1 << ViewIndex)) { //Essentially, which camera we are using const FSceneView* View = Views[ViewIndex]; //Ask for a new render batch and link it to our data FMeshBatch& Mesh = Collector.AllocateMesh(); Mesh.VertexFactory = &VertexFactory; Mesh.MaterialRenderProxy = Material->GetRenderProxy(IsSelected()); Mesh.ReverseCulling = IsLocalToWorldDeterminantNegative(); Mesh.DepthPriorityGroup = SDPG_World; Mesh.bCanApplyViewModeOverrides = false; //GL_Points render, still need to work out how to set GL_PointSize Mesh.Type = PT_PointList; //Tell the render object how to index our data. FMeshBatchElement& BatchElement = Mesh.Elements[0]; BatchElement.IndexBuffer = &IndexBuffer; //Give all the "default" uniforms to help render. (Transform etc.) BatchElement.PrimitiveUniformBuffer = CreatePrimitiveUniformBufferImmediate(GetLocalToWorld(), GetBounds(), GetLocalBounds(), true, UseEditorDepthTest()); BatchElement.FirstIndex = 0; BatchElement.NumPrimitives = IndexBuffer.Indices.Num() / 3; BatchElement.MinVertexIndex = 0; BatchElement.MaxVertexIndex = VertexBuffer.Vertices.Num() - 1; //All done! Collector.AddMesh(ViewIndex, Mesh); } } }
void FGeometryCacheSceneProxy::GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const { SCOPE_CYCLE_COUNTER(STAT_GeometryCacheSceneProxy_GetMeshElements); // Set up wireframe material (if needed) const bool bWireframe = AllowDebugViewmodes() && ViewFamily.EngineShowFlags.Wireframe; FColoredMaterialRenderProxy* WireframeMaterialInstance = NULL; if (bWireframe) { WireframeMaterialInstance = new FColoredMaterialRenderProxy( GEngine->WireframeMaterial ? GEngine->WireframeMaterial->GetRenderProxy(IsSelected()) : NULL, FLinearColor(0, 0.5f, 1.f) ); Collector.RegisterOneFrameMaterialProxy(WireframeMaterialInstance); } // Iterate over sections for (const FGeomCacheTrackProxy* TrackProxy : Sections ) { // QQQ if (TrackProxy != nullptr) { INC_DWORD_STAT_BY(STAT_GeometryCacheSceneProxy_MeshBatchCount, TrackProxy->MeshData->BatchesInfo.Num()); int32 BatchIndex = 0; for (FGeometryCacheMeshBatchInfo& BatchInfo : TrackProxy->MeshData->BatchesInfo) { FMaterialRenderProxy* MaterialProxy = bWireframe ? WireframeMaterialInstance : TrackProxy->Materials[BatchIndex]->GetRenderProxy(IsSelected()); for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { if (VisibilityMap & (1 << ViewIndex)) { const FSceneView* View = Views[ViewIndex]; // Draw the mesh. FMeshBatch& Mesh = Collector.AllocateMesh(); FMeshBatchElement& BatchElement = Mesh.Elements[0]; BatchElement.IndexBuffer = &TrackProxy->IndexBuffer; Mesh.bWireframe = bWireframe; Mesh.VertexFactory = &TrackProxy->VertexFactory; Mesh.MaterialRenderProxy = MaterialProxy; BatchElement.PrimitiveUniformBuffer = CreatePrimitiveUniformBufferImmediate(TrackProxy->WorldMatrix * GetLocalToWorld(), GetBounds(), GetLocalBounds(), true, UseEditorDepthTest()); BatchElement.FirstIndex = BatchInfo.StartIndex; BatchElement.NumPrimitives = BatchInfo.NumTriangles; BatchElement.MinVertexIndex = 0; BatchElement.MaxVertexIndex = TrackProxy->VertexBuffer.Vertices.Num() - 1; Mesh.ReverseCulling = IsLocalToWorldDeterminantNegative(); Mesh.Type = PT_TriangleList; Mesh.DepthPriorityGroup = SDPG_World; Mesh.bCanApplyViewModeOverrides = false; Collector.AddMesh(ViewIndex, Mesh); INC_DWORD_STAT_BY(STAT_GeometryCacheSceneProxy_TriangleCount, BatchElement.NumPrimitives); } } ++BatchIndex; } } } // Draw bounds #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { if (VisibilityMap & (1 << ViewIndex)) { // Render bounds RenderBounds(Collector.GetPDI(ViewIndex), ViewFamily.EngineShowFlags, GetBounds(), IsSelected()); } } #endif }
void FPaperTileMapRenderSceneProxy::GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const { QUICK_SCOPE_CYCLE_COUNTER(STAT_FPaperTileMapRenderSceneProxy_GetDynamicMeshElements); checkSlow(IsInRenderingThread()); // Slight depth bias so that the wireframe grid overlay doesn't z-fight with the tiles themselves const float DepthBias = 0.0001f; for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { if (VisibilityMap & (1 << ViewIndex)) { const FSceneView* View = Views[ViewIndex]; FPrimitiveDrawInterface* PDI = Collector.GetPDI(ViewIndex); // Draw the tile maps //@TODO: RenderThread race condition if (TileMap != nullptr) { FColor WireframeColor = FColor(0, 255, 255, 255); if ((View->Family->EngineShowFlags.Collision /*@TODO: && bIsCollisionEnabled*/) && AllowDebugViewmodes()) { if (UBodySetup2D* BodySetup2D = Cast<UBodySetup2D>(TileMap->BodySetup)) { //@TODO: Draw 2D debugging geometry } else if (UBodySetup* BodySetup = TileMap->BodySetup) { if (FMath::Abs(GetLocalToWorld().Determinant()) < SMALL_NUMBER) { // Catch this here or otherwise GeomTransform below will assert // This spams so commented out //UE_LOG(LogStaticMesh, Log, TEXT("Zero scaling not supported (%s)"), *StaticMesh->GetPathName()); } else { // Make a material for drawing solid collision stuff const UMaterial* LevelColorationMaterial = View->Family->EngineShowFlags.Lighting ? GEngine->ShadedLevelColorationLitMaterial : GEngine->ShadedLevelColorationUnlitMaterial; auto CollisionMaterialInstance = new FColoredMaterialRenderProxy( LevelColorationMaterial->GetRenderProxy(IsSelected(), IsHovered()), WireframeColor ); // Draw the static mesh's body setup. // Get transform without scaling. FTransform GeomTransform(GetLocalToWorld()); // In old wireframe collision mode, always draw the wireframe highlighted (selected or not). bool bDrawWireSelected = IsSelected(); if (View->Family->EngineShowFlags.Collision) { bDrawWireSelected = true; } // Differentiate the color based on bBlockNonZeroExtent. Helps greatly with skimming a level for optimization opportunities. FColor CollisionColor = FColor(157, 149, 223, 255); const bool bPerHullColor = false; const bool bDrawSimpleSolid = false; BodySetup->AggGeom.GetAggGeom(GeomTransform, GetSelectionColor(CollisionColor, bDrawWireSelected, IsHovered()), CollisionMaterialInstance, bPerHullColor, bDrawSimpleSolid, UseEditorDepthTest(), ViewIndex, Collector); } } } // Draw the bounds RenderBounds(PDI, View->Family->EngineShowFlags, GetBounds(), IsSelected()); #if WITH_EDITOR // Draw the debug outline if (View->Family->EngineShowFlags.Grid) { const uint8 DPG = SDPG_Foreground;//GetDepthPriorityGroup(View); // Draw separation wires if selected FLinearColor OverrideColor; bool bUseOverrideColor = false; const bool bShowAsSelected = !(GIsEditor && View->Family->EngineShowFlags.Selection) || IsSelected(); if (bShowAsSelected || IsHovered()) { bUseOverrideColor = true; OverrideColor = GetSelectionColor(FLinearColor::White, bShowAsSelected, IsHovered()); } FTransform LocalToWorld(GetLocalToWorld()); if (bUseOverrideColor) { const int32 SelectedLayerIndex = TileMap->SelectedLayerIndex; // Draw a bound for any invisible layers for (int32 LayerIndex = 0; LayerIndex < TileMap->TileLayers.Num(); ++LayerIndex) { if (LayerIndex != SelectedLayerIndex) { const FVector TL(LocalToWorld.TransformPosition(TileMap->GetTilePositionInLocalSpace(0, 0, LayerIndex))); const FVector TR(LocalToWorld.TransformPosition(TileMap->GetTilePositionInLocalSpace(TileMap->MapWidth, 0, LayerIndex))); const FVector BL(LocalToWorld.TransformPosition(TileMap->GetTilePositionInLocalSpace(0, TileMap->MapHeight, LayerIndex))); const FVector BR(LocalToWorld.TransformPosition(TileMap->GetTilePositionInLocalSpace(TileMap->MapWidth, TileMap->MapHeight, LayerIndex))); PDI->DrawLine(TL, TR, OverrideColor, DPG, 0.0f, DepthBias); PDI->DrawLine(TR, BR, OverrideColor, DPG, 0.0f, DepthBias); PDI->DrawLine(BR, BL, OverrideColor, DPG, 0.0f, DepthBias); PDI->DrawLine(BL, TL, OverrideColor, DPG, 0.0f, DepthBias); } } if (SelectedLayerIndex != INDEX_NONE) { // Draw horizontal lines on the selection for (int32 Y = 0; Y <= TileMap->MapHeight; ++Y) { int32 X = 0; const FVector Start(TileMap->GetTilePositionInLocalSpace(X, Y, SelectedLayerIndex)); X = TileMap->MapWidth; const FVector End(TileMap->GetTilePositionInLocalSpace(X, Y, SelectedLayerIndex)); PDI->DrawLine(LocalToWorld.TransformPosition(Start), LocalToWorld.TransformPosition(End), OverrideColor, DPG, 0.0f, DepthBias); } // Draw vertical lines for (int32 X = 0; X <= TileMap->MapWidth; ++X) { int32 Y = 0; const FVector Start(TileMap->GetTilePositionInLocalSpace(X, Y, SelectedLayerIndex)); Y = TileMap->MapHeight; const FVector End(TileMap->GetTilePositionInLocalSpace(X, Y, SelectedLayerIndex)); PDI->DrawLine(LocalToWorld.TransformPosition(Start), LocalToWorld.TransformPosition(End), OverrideColor, DPG, 0.0f, DepthBias); } } } } #endif } } } // Draw all of the queued up sprites FPaperRenderSceneProxy::GetDynamicMeshElements(Views, ViewFamily, VisibilityMap, Collector); }
void FPaperTileMapRenderSceneProxy::GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const { SCOPE_CYCLE_COUNTER(STAT_TileMap_GetDynamicMeshElements); checkSlow(IsInRenderingThread()); for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { SCOPE_CYCLE_COUNTER(STAT_TileMap_EditorWireDrawing); if (VisibilityMap & (1 << ViewIndex)) { const FSceneView* View = Views[ViewIndex]; FPrimitiveDrawInterface* PDI = Collector.GetPDI(ViewIndex); // Draw the tile maps //@TODO: RenderThread race condition if (TileMap != nullptr) { if ((View->Family->EngineShowFlags.Collision /*@TODO: && bIsCollisionEnabled*/) && AllowDebugViewmodes()) { if (UBodySetup2D* BodySetup2D = Cast<UBodySetup2D>(TileMap->BodySetup)) { //@TODO: Draw 2D debugging geometry } else if (UBodySetup* BodySetup = TileMap->BodySetup) { if (FMath::Abs(GetLocalToWorld().Determinant()) < SMALL_NUMBER) { // Catch this here or otherwise GeomTransform below will assert // This spams so commented out //UE_LOG(LogStaticMesh, Log, TEXT("Zero scaling not supported (%s)"), *StaticMesh->GetPathName()); } else { // Make a material for drawing solid collision stuff const UMaterial* LevelColorationMaterial = View->Family->EngineShowFlags.Lighting ? GEngine->ShadedLevelColorationLitMaterial : GEngine->ShadedLevelColorationUnlitMaterial; auto CollisionMaterialInstance = new FColoredMaterialRenderProxy( LevelColorationMaterial->GetRenderProxy(IsSelected(), IsHovered()), WireframeColor ); // Draw the static mesh's body setup. // Get transform without scaling. FTransform GeomTransform(GetLocalToWorld()); // In old wireframe collision mode, always draw the wireframe highlighted (selected or not). bool bDrawWireSelected = IsSelected(); if (View->Family->EngineShowFlags.Collision) { bDrawWireSelected = true; } // Differentiate the color based on bBlockNonZeroExtent. Helps greatly with skimming a level for optimization opportunities. FColor CollisionColor = FColor(157, 149, 223, 255); const bool bPerHullColor = false; const bool bDrawSimpleSolid = false; BodySetup->AggGeom.GetAggGeom(GeomTransform, GetSelectionColor(CollisionColor, bDrawWireSelected, IsHovered()).ToFColor(true), CollisionMaterialInstance, bPerHullColor, bDrawSimpleSolid, UseEditorDepthTest(), ViewIndex, Collector); } } } // Draw the bounds RenderBounds(PDI, View->Family->EngineShowFlags, GetBounds(), IsSelected()); #if WITH_EDITOR const bool bShowAsSelected = IsSelected(); const bool bEffectivelySelected = bShowAsSelected || IsHovered(); const uint8 DPG = SDPG_Foreground;//GetDepthPriorityGroup(View); // Draw separation wires if selected const FLinearColor OverrideColor = GetSelectionColor(FLinearColor::White, bShowAsSelected, IsHovered(), /*bUseOverlayIntensity=*/ false); // Draw the debug outline if (bEffectivelySelected) { const int32 SelectedLayerIndex = (OnlyLayerIndex != INDEX_NONE) ? OnlyLayerIndex : TileMap->SelectedLayerIndex; if (bShowPerLayerGrid) { if (OnlyLayerIndex == INDEX_NONE) { // Draw a bound for every layer but the selected one (and even that one if the per-tile grid is off) for (int32 LayerIndex = 0; LayerIndex < TileMap->TileLayers.Num(); ++LayerIndex) { if ((LayerIndex != SelectedLayerIndex) || !bShowPerTileGrid) { DrawBoundsForLayer(PDI, OverrideColor, LayerIndex); } } } else if (!bShowPerTileGrid) { DrawBoundsForLayer(PDI, OverrideColor, OnlyLayerIndex); } } if (bShowPerTileGrid && (SelectedLayerIndex != INDEX_NONE)) { switch (TileMap->ProjectionMode) { default: case ETileMapProjectionMode::Orthogonal: case ETileMapProjectionMode::IsometricDiamond: DrawNormalGridLines(PDI, OverrideColor, SelectedLayerIndex); break; case ETileMapProjectionMode::IsometricStaggered: DrawStaggeredGridLines(PDI, OverrideColor, SelectedLayerIndex); break; case ETileMapProjectionMode::HexagonalStaggered: DrawHexagonalGridLines(PDI, OverrideColor, SelectedLayerIndex); break; } } } else if (View->Family->EngineShowFlags.Grid && bShowOutlineWhenUnselected) { // Draw a layer rectangle even when not selected, so you can see where the tile map is in the editor DrawBoundsForLayer(PDI, WireframeColor, /*LayerIndex=*/ (OnlyLayerIndex != INDEX_NONE) ? OnlyLayerIndex : 0); } #endif } } } // Draw all of the queued up sprites FPaperRenderSceneProxy::GetDynamicMeshElements(Views, ViewFamily, VisibilityMap, Collector); }