diff --git a/Source/StreetMapRuntime/StreetMapComponent.cpp b/Source/StreetMapRuntime/StreetMapComponent.cpp index 680dfaa..3d0c932 100644 --- a/Source/StreetMapRuntime/StreetMapComponent.cpp +++ b/Source/StreetMapRuntime/StreetMapComponent.cpp @@ -170,11 +170,8 @@ void UStreetMapComponent::GenerateCollision() } // Rebuild the body setup -#if WITH_EDITOR || WITH_RUNTIME_PHYSICS_COOKING StreetMapBodySetup->InvalidatePhysicsData(); -#endif StreetMapBodySetup->CreatePhysicsMeshes(); - UpdateNavigationIfNeeded(); } diff --git a/Source/StreetMapRuntime/StreetMapSceneProxy.cpp b/Source/StreetMapRuntime/StreetMapSceneProxy.cpp index e49de13..c840769 100644 --- a/Source/StreetMapRuntime/StreetMapSceneProxy.cpp +++ b/Source/StreetMapRuntime/StreetMapSceneProxy.cpp @@ -6,152 +6,84 @@ #include "Runtime/Engine/Public/SceneManagement.h" -void FStreetMapVertexBuffer::InitRHI() -{ - if( Vertices.Num() > 0 ) - { - // Allocate our vertex buffer - FRHIResourceCreateInfo CreateInfo; - VertexBufferRHI = RHICreateVertexBuffer( Vertices.Num() * sizeof( Vertices[0] ), BUF_Static, CreateInfo ); - - // Load the vertex buffer with data - void* VertexBufferData = RHILockVertexBuffer( VertexBufferRHI, 0, Vertices.Num() * sizeof( Vertices[0] ), RLM_WriteOnly ); - FMemory::Memcpy( VertexBufferData, Vertices.GetData(), Vertices.Num() * sizeof( FStreetMapVertex ) ); - RHIUnlockVertexBuffer( VertexBufferRHI ); - } -} - - -void FStreetMapIndexBuffer::InitRHI() -{ - const int IndexCount = FMath::Max( Indices16.Num(), Indices32.Num() ); - if( IndexCount > 0 ) - { - const bool b32BitIndices = Indices32.Num() > Indices16.Num(); - const uint8 IndexSize = b32BitIndices ? sizeof( Indices32[ 0 ] ) : sizeof( Indices16[ 0 ] ); - const void* IndexSourceData; - if( b32BitIndices ) - { - IndexSourceData = Indices32.GetData(); - } - else - { - IndexSourceData = Indices16.GetData(); - } - - // Allocate our index buffer and load it with data - FRHIResourceCreateInfo CreateInfo; - IndexBufferRHI = RHICreateIndexBuffer( IndexSize, IndexCount * IndexSize, BUF_Static, CreateInfo ); - void* IndexBufferData = RHILockIndexBuffer( IndexBufferRHI, 0, IndexCount * IndexSize, RLM_WriteOnly ); - FMemory::Memcpy( IndexBufferData, IndexSourceData, IndexCount * IndexSize ); - RHIUnlockIndexBuffer( IndexBufferRHI ); - } -} - - -void FStreetMapVertexFactory::InitVertexFactory( const FStreetMapVertexBuffer& VertexBuffer ) -{ - // Setup the vertex factory streams - FDataType DataType; - DataType.PositionComponent = STRUCTMEMBER_VERTEXSTREAMCOMPONENT( &VertexBuffer, FStreetMapVertex, Position, VET_Float3 ); - DataType.TextureCoordinates.Add( STRUCTMEMBER_VERTEXSTREAMCOMPONENT( &VertexBuffer, FStreetMapVertex, TextureCoordinate, VET_Float2 ) ); - DataType.TangentBasisComponents[0] = STRUCTMEMBER_VERTEXSTREAMCOMPONENT( &VertexBuffer, FStreetMapVertex, TangentX, VET_PackedNormal); - DataType.TangentBasisComponents[1] = STRUCTMEMBER_VERTEXSTREAMCOMPONENT( &VertexBuffer, FStreetMapVertex, TangentZ, VET_PackedNormal); - DataType.ColorComponent = STRUCTMEMBER_VERTEXSTREAMCOMPONENT( &VertexBuffer, FStreetMapVertex, Color, VET_Color ); - - // Send it off to the rendering thread - check( !IsInActualRenderingThread() ); - ENQUEUE_UNIQUE_RENDER_COMMAND_TWOPARAMETER( - InitStreetMapVertexFactory, - FStreetMapVertexFactory*, VertexFactory, this, - FDataType, DataType, DataType, - { - VertexFactory->SetData( DataType ); - }); -} - - FStreetMapSceneProxy::FStreetMapSceneProxy(const UStreetMapComponent* InComponent) : FPrimitiveSceneProxy(InComponent), StreetMapComp(InComponent), - CollisionResponse(InComponent->GetCollisionResponseToChannels()) + CollisionResponse(InComponent->GetCollisionResponseToChannels()), + VertexFactory(GetScene().GetFeatureLevel(), "FStreetMapSceneProxy") { } - -void FStreetMapSceneProxy::Init( const UStreetMapComponent* InComponent, const TArray< FStreetMapVertex >& Vertices, const TArray< uint16 >& Indices ) +void FStreetMapSceneProxy::Init(const UStreetMapComponent* InComponent, const TArray< FStreetMapVertex >& Vertices, const TArray< uint32 >& Indices) { - // Copy 16-bit index data - IndexBuffer.Indices16 = Indices; - - InitAfterIndexBuffer( InComponent, Vertices ); -} + // Copy index buffer + IndexBuffer32.Indices = Indices; + MaterialInterface = nullptr; + this->MaterialRelevance = InComponent->GetMaterialRelevance(GetScene().GetFeatureLevel()); -void FStreetMapSceneProxy::Init( const UStreetMapComponent* InComponent, const TArray< FStreetMapVertex >& Vertices, const TArray< uint32 >& Indices ) -{ - // If we fit into a 16-bit index buffer, just use that - if( Vertices.Num() < 0xffff ) - { - const int32 IndexCount = Indices.Num(); - IndexBuffer.Indices16.AddUninitialized( IndexCount ); - for( int32 Index = 0; Index < IndexCount; ++Index ) - { - IndexBuffer.Indices16[ Index ] = Indices[ Index ]; - } - } - else - { - // Copy 32-bit index data - IndexBuffer.Indices32 = Indices; - } - - InitAfterIndexBuffer( InComponent, Vertices ); -} -void FStreetMapSceneProxy::InitAfterIndexBuffer( const UStreetMapComponent* StreetMapComponent, const TArray< FStreetMapVertex >& Vertices ) -{ - MaterialInterface = nullptr; - this->MaterialRelevance = StreetMapComponent->GetMaterialRelevance( GetScene().GetFeatureLevel() ); - // Copy vertex data - VertexBuffer.Vertices = Vertices; + const int32 NumVerts = Vertices.Num(); + TArray DynamicVertices; + DynamicVertices.SetNumUninitialized(NumVerts); + + for (int VertIdx = 0; VertIdx < NumVerts; VertIdx++) + { + const FStreetMapVertex& StreetMapVert = Vertices[VertIdx]; + FDynamicMeshVertex& Vert = DynamicVertices[VertIdx]; + Vert.Position = StreetMapVert.Position; + Vert.Color = StreetMapVert.Color; + Vert.TextureCoordinate[0] = StreetMapVert.TextureCoordinate; + Vert.TangentX = StreetMapVert.TangentX; + Vert.TangentZ = StreetMapVert.TangentZ; + } + + VertexBuffer.InitFromDynamicVertex(&VertexFactory, DynamicVertices); + + // Enqueue initialization of render resource InitResources(); - + // Set a material { - if( StreetMapComponent->GetNumMaterials() > 0 ) + if (InComponent->GetNumMaterials() > 0) { - MaterialInterface = StreetMapComponent->GetMaterial( 0 ); + MaterialInterface = InComponent->GetMaterial(0); } - + // Use the default material if we don't have one set - if( MaterialInterface == nullptr ) + if (MaterialInterface == nullptr) { - MaterialInterface = UMaterial::GetDefaultMaterial( MD_Surface ); + MaterialInterface = UMaterial::GetDefaultMaterial(MD_Surface); } } } - - FStreetMapSceneProxy::~FStreetMapSceneProxy() { - VertexBuffer.ReleaseResource(); - IndexBuffer.ReleaseResource(); + VertexBuffer.PositionVertexBuffer.ReleaseResource(); + VertexBuffer.StaticMeshVertexBuffer.ReleaseResource(); + VertexBuffer.ColorVertexBuffer.ReleaseResource(); + IndexBuffer32.ReleaseResource(); VertexFactory.ReleaseResource(); } +SIZE_T FStreetMapSceneProxy::GetTypeHash() const +{ + static size_t UniquePointer; + return reinterpret_cast(&UniquePointer); +} + void FStreetMapSceneProxy::InitResources() { - // Start initializing our vertex buffer, index buffer, and vertex factory. This will be kicked off on the render thread. - BeginInitResource( &VertexBuffer ); - BeginInitResource( &IndexBuffer ); - - VertexFactory.InitVertexFactory( VertexBuffer ); - BeginInitResource( &VertexFactory ); + // Start initializing our vertex buffer, index buffer, and vertex factory. This will be kicked off on the render thread. + BeginInitResource(&VertexBuffer.PositionVertexBuffer); + BeginInitResource(&VertexBuffer.StaticMeshVertexBuffer); + BeginInitResource(&VertexBuffer.ColorVertexBuffer); + BeginInitResource(&IndexBuffer32); + BeginInitResource(&VertexFactory); } @@ -209,17 +141,17 @@ void FStreetMapSceneProxy::MakeMeshBatch( FMeshBatch& Mesh, FMaterialRenderProxy } FMeshBatchElement& BatchElement = Mesh.Elements[0]; - BatchElement.IndexBuffer = &IndexBuffer; + BatchElement.IndexBuffer = &IndexBuffer32; Mesh.bWireframe = WireframeMaterialRenderProxyOrNull != nullptr; Mesh.VertexFactory = &VertexFactory; Mesh.MaterialRenderProxy = MaterialProxy; Mesh.CastShadow = true; BatchElement.PrimitiveUniformBuffer = CreatePrimitiveUniformBufferImmediate(GetLocalToWorld(), GetBounds(), GetLocalBounds(), true, UseEditorDepthTest()); BatchElement.FirstIndex = 0; - const int IndexCount = FMath::Max( IndexBuffer.Indices16.Num(), IndexBuffer.Indices32.Num() ); + const int IndexCount = IndexBuffer32.Indices.Num(); BatchElement.NumPrimitives = IndexCount / 3; BatchElement.MinVertexIndex = 0; - BatchElement.MaxVertexIndex = VertexBuffer.Vertices.Num() - 1; + BatchElement.MaxVertexIndex = VertexBuffer.PositionVertexBuffer.GetNumVertices() - 1; Mesh.ReverseCulling = IsLocalToWorldDeterminantNegative(); Mesh.Type = PT_TriangleList; Mesh.DepthPriorityGroup = SDPG_World; @@ -228,8 +160,8 @@ void FStreetMapSceneProxy::MakeMeshBatch( FMeshBatch& Mesh, FMaterialRenderProxy void FStreetMapSceneProxy::DrawStaticElements( FStaticPrimitiveDrawInterface* PDI ) { - const int IndexCount = FMath::Max( IndexBuffer.Indices16.Num(), IndexBuffer.Indices32.Num() ); - if( VertexBuffer.Vertices.Num() > 0 && IndexCount > 0 ) + const int IndexCount = IndexBuffer32.Indices.Num(); + if( VertexBuffer.PositionVertexBuffer.GetNumVertices() > 0 && IndexCount > 0 ) { const float ScreenSize = 1.0f; @@ -242,8 +174,8 @@ void FStreetMapSceneProxy::DrawStaticElements( FStaticPrimitiveDrawInterface* PD void FStreetMapSceneProxy::GetDynamicMeshElements(const TArray& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, class FMeshElementCollector& Collector) const { - const int IndexCount = FMath::Max(IndexBuffer.Indices16.Num(), IndexBuffer.Indices32.Num()); - if (VertexBuffer.Vertices.Num() > 0 && IndexCount > 0) + const int IndexCount = IndexBuffer32.Indices.Num(); + if (VertexBuffer.PositionVertexBuffer.GetNumVertices() > 0 && IndexCount > 0) { for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ++ViewIndex) { diff --git a/Source/StreetMapRuntime/StreetMapSceneProxy.h b/Source/StreetMapRuntime/StreetMapSceneProxy.h index feb17f5..a6758b7 100644 --- a/Source/StreetMapRuntime/StreetMapSceneProxy.h +++ b/Source/StreetMapRuntime/StreetMapSceneProxy.h @@ -3,6 +3,7 @@ #include "Runtime/Engine/Public/PrimitiveSceneProxy.h" #include "Runtime/Engine/Public/LocalVertexFactory.h" +#include "Runtime/Engine/Public/DynamicMeshBuilder.h" #include "StreetMapSceneProxy.generated.h" /** A single vertex on a street map mesh */ @@ -50,50 +51,6 @@ struct FStreetMapVertex }; -/** Street map mesh vertex buffer */ -class FStreetMapVertexBuffer : public FVertexBuffer -{ - -public: - - /** All of the vertices in this mesh */ - TArray< FStreetMapVertex > Vertices; - - - // FRenderResource interface - virtual void InitRHI() override; -}; - - -/** Street map mesh index buffer */ -class FStreetMapIndexBuffer : public FIndexBuffer -{ - -public: - - /** 16-bit indices */ - TArray< uint16 > Indices16; - - /** 32-bit indices */ - TArray< uint32 > Indices32; - - - // FRenderResource interface - virtual void InitRHI() override; -}; - - -/** Street map mesh vertex factory */ -class FStreetMapVertexFactory : public FLocalVertexFactory -{ - -public: - - /** Initialize this vertex factory */ - void InitVertexFactory( const FStreetMapVertexBuffer& VertexBuffer ); -}; - - /** Scene proxy for rendering a section of a street map mesh on the rendering thread */ class FStreetMapSceneProxy : public FPrimitiveSceneProxy { @@ -112,24 +69,15 @@ class FStreetMapSceneProxy : public FPrimitiveSceneProxy */ void Init(const UStreetMapComponent* InComponent, const TArray< FStreetMapVertex >& Vertices, const TArray< uint32 >& Indices); - /** - * Init this street map mesh scene proxy for the specified component (16-bit indices) - * - * @param InComponent The street map mesh component to initialize this with - * @param Vertices The vertices for this street map mesh - * @param Indices The vertex indices for this street map mesh - */ - void Init(const UStreetMapComponent* InComponent, const TArray< FStreetMapVertex >& Vertices, const TArray< uint16 >& Indices); - /** Destructor that cleans up our rendering data */ virtual ~FStreetMapSceneProxy(); - + + + /** Return a type (or subtype) specific hash for sorting purposes */ + SIZE_T GetTypeHash() const override; protected: - /** Called from the constructor to finish construction after the index buffer is setup */ - void InitAfterIndexBuffer(const class UStreetMapComponent* StreetMapComponent, const TArray< FStreetMapVertex >& Vertices); - /** Initializes this scene proxy's vertex buffer, index buffer and vertex factory (on the render thread.) */ void InitResources(); @@ -150,20 +98,16 @@ class FStreetMapSceneProxy : public FPrimitiveSceneProxy virtual FPrimitiveViewRelevance GetViewRelevance(const class FSceneView* View) const override; virtual bool CanBeOccluded() const override; - - protected: - - - - /** Contains all of the vertices in our street map mesh */ - FStreetMapVertexBuffer VertexBuffer; - - /** All of the vertex indices in our street map mesh */ - FStreetMapIndexBuffer IndexBuffer; - - /** Our vertex factory specific to street map meshes */ - FStreetMapVertexFactory VertexFactory; + + /** Contains all of the vertices in our street map mesh */ + FStaticMeshVertexBuffers VertexBuffer; + + /** All of the vertex indices32 in our street map mesh */ + FDynamicMeshIndexBuffer32 IndexBuffer32; + + /** Our vertex factory specific to street map meshes */ + FLocalVertexFactory VertexFactory; /** Cached material relevance */ FMaterialRelevance MaterialRelevance; @@ -175,6 +119,4 @@ class FStreetMapSceneProxy : public FPrimitiveSceneProxy // The Collision Response of the component being proxied FCollisionResponseContainer CollisionResponse; - - };