Files
UnrealEngineUWP/Engine/Source/Runtime/Experimental/GeometryCollectionEngine/Private/GeometryCollection/GeometryCollectionSceneProxy.cpp
Marcus Wassmer 3c30baa4f9 Merging //UE4/Dev-Main@4661957 to Dev-Rendering (//UE4/Dev-Rendering)
#rb none
Contains temporary removal of some FGeometryCollectionSceneProxy code that is not compatible with refactor.

[CL 4664599 by Marcus Wassmer in Dev-Rendering branch]
2018-12-15 14:19:22 -05:00

352 lines
13 KiB
C++

// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.
#include "GeometryCollection/GeometryCollectionSceneProxy.h"
#include "Async/ParallelFor.h"
#include "Engine/Engine.h"
#include "Materials/Material.h"
#include "GeometryCollection/GeometryCollectionComponent.h"
DEFINE_LOG_CATEGORY_STATIC(FGeometryCollectionSceneProxyLogging, Log, All);
FGeometryCollectionSceneProxy::FGeometryCollectionSceneProxy(UGeometryCollectionComponent* Component)
: FPrimitiveSceneProxy(Component)
, MaterialRelevance(Component->GetMaterialRelevance(GetScene().GetFeatureLevel()))
, NumVertices(0)
, NumIndices(0)
, VertexFactory(GetScene().GetFeatureLevel(), "FGeometryCollectionSceneProxy")
, DynamicData(nullptr)
, ConstantData(nullptr)
, ShowBoneColors(Component->GetShowBoneColors())
, ShowSelectedBones(Component->GetShowSelectedBones())
, BoneSelectionMaterialID(Component->GetBoneSelectedMaterialID())
{
Materials.Empty();
for (int MaterialIndex = 0; MaterialIndex < Component->GetNumMaterials(); MaterialIndex++)
{
Materials.Push(Component->GetMaterial(MaterialIndex));
if (Materials[MaterialIndex] == nullptr)
{
Materials[MaterialIndex] = UMaterial::GetDefaultMaterial(MD_Surface);
}
}
}
FGeometryCollectionSceneProxy::~FGeometryCollectionSceneProxy()
{
ReleaseResources();
if (DynamicData != nullptr)
{
delete DynamicData;
}
if (ConstantData != nullptr)
{
delete ConstantData;
}
}
void FGeometryCollectionSceneProxy::InitResources()
{
check(ConstantData);
NumVertices = ConstantData->Vertices.Num();
NumIndices = ConstantData->Indices.Num()*3;
VertexBuffers.InitWithDummyData(&VertexFactory, GetRequiredVertexCount());
IndexBuffer.NumIndices = GetRequiredIndexCount();
BeginInitResource(&IndexBuffer);
}
void FGeometryCollectionSceneProxy::ReleaseResources()
{
VertexBuffers.PositionVertexBuffer.ReleaseResource();
VertexBuffers.StaticMeshVertexBuffer.ReleaseResource();
VertexBuffers.ColorVertexBuffer.ReleaseResource();
IndexBuffer.ReleaseResource();
VertexFactory.ReleaseResource();
}
void FGeometryCollectionSceneProxy::BuildGeometry( const FGeometryCollectionConstantData* ConstantDataIn, TArray<FDynamicMeshVertex>& OutVertices, TArray<int32>& OutIndices)
{
OutVertices.SetNumUninitialized(ConstantDataIn->Vertices.Num());
ParallelFor(ConstantData->Vertices.Num(), [&](int32 PointIdx)
{
OutVertices[PointIdx] =
FDynamicMeshVertex(
ConstantDataIn->Vertices[PointIdx],
ConstantDataIn->UVs[PointIdx],
ShowBoneColors||ShowSelectedBones ?
ConstantDataIn->BoneColors[PointIdx].ToFColor(true) :
ConstantDataIn->Colors[PointIdx].ToFColor(true)
);
OutVertices[PointIdx].SetTangents(ConstantDataIn->TangentU[PointIdx], ConstantDataIn->TangentV[PointIdx], ConstantDataIn->Normals[PointIdx]);
});
check(ConstantDataIn->Indices.Num() * 3 == NumIndices);
OutIndices.SetNumUninitialized(NumIndices);
ParallelFor (ConstantDataIn->Indices.Num(), [&](int32 IndexIdx)
{
OutIndices[IndexIdx * 3 ] = ConstantDataIn->Indices[IndexIdx].X;
OutIndices[IndexIdx * 3 + 1] = ConstantDataIn->Indices[IndexIdx].Y;
OutIndices[IndexIdx * 3 + 2] = ConstantDataIn->Indices[IndexIdx].Z;
});
}
void FGeometryCollectionSceneProxy::SetConstantData_RenderThread(FGeometryCollectionConstantData* NewConstantData, bool ForceInit)
{
check(IsInRenderingThread());
check(NewConstantData);
if (ConstantData)
{
delete ConstantData;
ConstantData = nullptr;
}
ConstantData = NewConstantData;
if (ConstantData->Vertices.Num() != VertexBuffers.PositionVertexBuffer.GetNumVertices() || ForceInit)
{
ReleaseResources();
InitResources();
}
TArray<int32> Indices;
TArray<FDynamicMeshVertex> Vertices;
BuildGeometry(ConstantData, Vertices, Indices);
check(Vertices.Num() == GetRequiredVertexCount());
check(Indices.Num() == GetRequiredIndexCount());
if (GetRequiredVertexCount())
{
ParallelFor(Vertices.Num(), [&](int32 i)
{
const FDynamicMeshVertex& Vertex = Vertices[i];
VertexBuffers.PositionVertexBuffer.VertexPosition(i) = Vertex.Position;
VertexBuffers.StaticMeshVertexBuffer.SetVertexTangents(i, Vertex.TangentX.ToFVector(), Vertex.GetTangentY(), Vertex.TangentZ.ToFVector());
VertexBuffers.StaticMeshVertexBuffer.SetVertexUV(i, 0, Vertex.TextureCoordinate[0]);
VertexBuffers.ColorVertexBuffer.VertexColor(i) = Vertex.Color;
});
{
auto& VertexBuffer = VertexBuffers.PositionVertexBuffer;
void* VertexBufferData = RHILockVertexBuffer(VertexBuffer.VertexBufferRHI, 0, VertexBuffer.GetNumVertices() * VertexBuffer.GetStride(), RLM_WriteOnly);
FMemory::Memcpy(VertexBufferData, VertexBuffer.GetVertexData(), VertexBuffer.GetNumVertices() * VertexBuffer.GetStride());
RHIUnlockVertexBuffer(VertexBuffer.VertexBufferRHI);
}
{
auto& VertexBuffer = VertexBuffers.ColorVertexBuffer;
void* VertexBufferData = RHILockVertexBuffer(VertexBuffer.VertexBufferRHI, 0, VertexBuffer.GetNumVertices() * VertexBuffer.GetStride(), RLM_WriteOnly);
FMemory::Memcpy(VertexBufferData, VertexBuffer.GetVertexData(), VertexBuffer.GetNumVertices() * VertexBuffer.GetStride());
RHIUnlockVertexBuffer(VertexBuffer.VertexBufferRHI);
}
{
auto& VertexBuffer = VertexBuffers.StaticMeshVertexBuffer;
void* VertexBufferData = RHILockVertexBuffer(VertexBuffer.TangentsVertexBuffer.VertexBufferRHI, 0, VertexBuffer.GetTangentSize(), RLM_WriteOnly);
FMemory::Memcpy(VertexBufferData, VertexBuffer.GetTangentData(), VertexBuffer.GetTangentSize());
RHIUnlockVertexBuffer(VertexBuffer.TangentsVertexBuffer.VertexBufferRHI);
}
{
auto& VertexBuffer = VertexBuffers.StaticMeshVertexBuffer;
void* VertexBufferData = RHILockVertexBuffer(VertexBuffer.TexCoordVertexBuffer.VertexBufferRHI, 0, VertexBuffer.GetTexCoordSize(), RLM_WriteOnly);
FMemory::Memcpy(VertexBufferData, VertexBuffer.GetTexCoordData(), VertexBuffer.GetTexCoordSize());
RHIUnlockVertexBuffer(VertexBuffer.TexCoordVertexBuffer.VertexBufferRHI);
}
{
void* IndexBufferData = RHILockIndexBuffer(IndexBuffer.IndexBufferRHI, 0, Indices.Num() * sizeof(int32), RLM_WriteOnly);
FMemory::Memcpy(IndexBufferData, &Indices[0], Indices.Num() * sizeof(int32));
RHIUnlockIndexBuffer(IndexBuffer.IndexBufferRHI);
}
Sections.Empty();
for (FGeometryCollectionSection Section : ConstantData->Sections)
{
if (Section.NumTriangles > 0)
{
FGeometryCollectionSection NewSection;
NewSection.MaterialID = Section.MaterialID;
NewSection.FirstIndex = Section.FirstIndex;
NewSection.NumTriangles = Section.NumTriangles;
NewSection.MinVertexIndex = Section.MinVertexIndex;
NewSection.MaxVertexIndex = Section.MaxVertexIndex;
Sections.Add(NewSection);
}
}
}
}
void FGeometryCollectionSceneProxy::SetDynamicData_RenderThread(FGeometryCollectionDynamicData* NewDynamicData)
{
check(IsInRenderingThread());
if (GetRequiredVertexCount())
{
if (DynamicData)
{
delete DynamicData;
DynamicData = nullptr;
}
DynamicData = NewDynamicData;
check(VertexBuffers.PositionVertexBuffer.GetNumVertices() == (uint32)ConstantData->Vertices.Num());
ParallelFor(ConstantData->Vertices.Num(), [&](int32 i)
{
VertexBuffers.PositionVertexBuffer.VertexPosition(i) = DynamicData->Transforms[ConstantData->BoneMap[i]].TransformPosition(ConstantData->Vertices[i]);
});
{
auto& VertexBuffer = VertexBuffers.PositionVertexBuffer;
void* VertexBufferData = RHILockVertexBuffer(VertexBuffer.VertexBufferRHI, 0, VertexBuffer.GetNumVertices() * VertexBuffer.GetStride(), RLM_WriteOnly);
FMemory::Memcpy(VertexBufferData, VertexBuffer.GetVertexData(), VertexBuffer.GetNumVertices() * VertexBuffer.GetStride());
RHIUnlockVertexBuffer(VertexBuffer.VertexBufferRHI);
}
}
}
FMaterialRenderProxy* FGeometryCollectionSceneProxy::GetMaterial(FMeshElementCollector& Collector, int32 MaterialIndex) const
{
//todo HLR
#if 0
// material for wireframe
auto WireframeMaterialInstance = new FColoredMaterialRenderProxy(
GEngine->WireframeMaterial ? GEngine->WireframeMaterial->GetRenderProxy(IsSelected()) : nullptr,
FLinearColor(0, 0.5f, 1.f)
);
Collector.RegisterOneFrameMaterialProxy(WireframeMaterialInstance);
// material for colored bones
UMaterial* VertexColorVisualizationMaterial = GEngine->VertexColorMaterial;
auto VertexColorVisualizationMaterialInstance = new FColoredMaterialRenderProxy(
VertexColorVisualizationMaterial->GetRenderProxy(false, false),
GetSelectionColor(FLinearColor::White, false, false)
);
Collector.RegisterOneFrameMaterialProxy(VertexColorVisualizationMaterialInstance);
FMaterialRenderProxy* MaterialProxy = nullptr;
if (ShowBoneColors)
{
MaterialProxy = VertexColorVisualizationMaterialInstance;
}
else
{
MaterialProxy = Materials[MaterialIndex]->GetRenderProxy(IsSelected());
}
if (MaterialProxy == nullptr)
{
MaterialProxy = UMaterial::GetDefaultMaterial(MD_Surface)->GetRenderProxy(IsSelected(), IsHovered());
}
return MaterialProxy;
#endif
return nullptr;
}
void FGeometryCollectionSceneProxy::GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const
{
#if 0
QUICK_SCOPE_CYCLE_COUNTER(STAT_GeometryCollectionSceneProxy_GetDynamicMeshElements);
if (GetRequiredVertexCount())
{
const bool bWireframe = AllowDebugViewmodes() && ViewFamily.EngineShowFlags.Wireframe;
for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++)
{
//Grab the material proxies we'll be using for each section
TArray<FMaterialRenderProxy*, TInlineAllocator<32>> MaterialProxies;
for (int SectionIndex = 0; SectionIndex < Sections.Num(); SectionIndex++)
{
const FGeometryCollectionSection& Section = Sections[SectionIndex];
FMaterialRenderProxy* MaterialProxy = GetMaterial(Collector, Section.MaterialID);
MaterialProxies.Add(MaterialProxy);
}
// Render Batches
for (int SectionIndex = 0; SectionIndex < Sections.Num(); SectionIndex++)
{
const FGeometryCollectionSection& Section = Sections[SectionIndex];
if (VisibilityMap & (1 << ViewIndex))
{
const FSceneView* View = Views[ViewIndex];
// Draw the mesh.
FMeshBatch& Mesh = Collector.AllocateMesh();
FMeshBatchElement& BatchElement = Mesh.Elements[0];
BatchElement.IndexBuffer = &IndexBuffer;
Mesh.bWireframe = bWireframe;
Mesh.VertexFactory = &VertexFactory;
Mesh.MaterialRenderProxy = MaterialProxies[SectionIndex];
BatchElement.PrimitiveUniformBuffer = CreatePrimitiveUniformBufferImmediate(GetLocalToWorld(), GetBounds(), GetLocalBounds(), true, UseEditorDepthTest());
BatchElement.FirstIndex = Section.FirstIndex;
BatchElement.NumPrimitives = Section.NumTriangles;
BatchElement.MinVertexIndex = Section.MinVertexIndex;
BatchElement.MaxVertexIndex = Section.MaxVertexIndex;
Mesh.ReverseCulling = IsLocalToWorldDeterminantNegative();
Mesh.Type = PT_TriangleList;
Mesh.DepthPriorityGroup = SDPG_World;
Mesh.bCanApplyViewModeOverrides = false;
Collector.AddMesh(ViewIndex, Mesh);
}
}
// Highlight selected bone using specialized material - when rendering bones as colors we don't need to run this code as the
// bone selection is already contained in the rendered colors
if (ShowBoneColors||ShowSelectedBones)
{
FMaterialRenderProxy* MaterialRenderProxy = Materials[BoneSelectionMaterialID]->GetRenderProxy(IsSelected());
if (VisibilityMap & (1 << ViewIndex))
{
const FSceneView* View = Views[ViewIndex];
FMeshBatch& Mesh = Collector.AllocateMesh();
FMeshBatchElement& BatchElement = Mesh.Elements[0];
BatchElement.IndexBuffer = &IndexBuffer;
Mesh.bWireframe = bWireframe;
Mesh.VertexFactory = &VertexFactory;
Mesh.MaterialRenderProxy = MaterialRenderProxy;
BatchElement.PrimitiveUniformBuffer = CreatePrimitiveUniformBufferImmediate(GetLocalToWorld(), GetBounds(), GetLocalBounds(), true, UseEditorDepthTest());
BatchElement.FirstIndex = 0;
BatchElement.NumPrimitives = GetRequiredIndexCount() / 3;
BatchElement.MinVertexIndex = 0;
BatchElement.MaxVertexIndex = GetRequiredVertexCount();
Mesh.ReverseCulling = IsLocalToWorldDeterminantNegative();
Mesh.Type = PT_TriangleList;
Mesh.DepthPriorityGroup = SDPG_World;
Mesh.bCanApplyViewModeOverrides = false;
Collector.AddMesh(ViewIndex, Mesh);
}
}
#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
if(VisibilityMap & (1 << ViewIndex))
{
RenderBounds(Collector.GetPDI(ViewIndex), ViewFamily.EngineShowFlags, GetBounds(), IsSelected());
}
#endif
}
}
#endif
}
FPrimitiveViewRelevance FGeometryCollectionSceneProxy::GetViewRelevance(const FSceneView* View) const
{
FPrimitiveViewRelevance Result;
Result.bDrawRelevance = IsShown(View);
Result.bShadowRelevance = IsShadowCast(View);
Result.bDynamicRelevance = true;
MaterialRelevance.SetPrimitiveViewRelevance(Result);
return Result;
}