From e210759e7b091b3842f17e8d21ef7b80d5185687 Mon Sep 17 00:00:00 2001 From: Steve Streeting Date: Mon, 25 Jul 2022 15:32:19 +0100 Subject: [PATCH] Add mesh support to visualisation component --- .../Private/StevesDebugRenderSceneProxy.cpp | 19 +++++++- .../Private/StevesEditorVisComponent.cpp | 35 ++++++++++++++ .../Public/StevesDebugRenderSceneProxy.h | 21 ++++++++- .../Public/StevesEditorVisComponent.h | 46 +++++++++++++++++++ .../StevesUEHelpers/StevesUEHelpers.Build.cs | 1 + 5 files changed, 120 insertions(+), 2 deletions(-) diff --git a/Source/StevesUEHelpers/Private/StevesDebugRenderSceneProxy.cpp b/Source/StevesUEHelpers/Private/StevesDebugRenderSceneProxy.cpp index 9818092..dffef11 100644 --- a/Source/StevesUEHelpers/Private/StevesDebugRenderSceneProxy.cpp +++ b/Source/StevesUEHelpers/Private/StevesDebugRenderSceneProxy.cpp @@ -9,7 +9,6 @@ void FStevesDebugRenderSceneProxy::GetDynamicMeshElements(const TArrayGetFeatureLevel()); + MeshBuilder.AddVertices(Mesh.Vertices); + MeshBuilder.AddTriangles(Mesh.Indices); + + // Parent caches these (only within this function) but let's assume that's not worth it. Will people really + // have lots of meshes with a shared colour in this single context to make it worth it? + const auto MatRenderProxy = new(FMemStack::Get()) FColoredMaterialRenderProxy(GEngine->WireframeMaterial->GetRenderProxy(), Mesh.Color); + FDynamicMeshBuilderSettings Settings; + Settings.bWireframe = true; + Settings.bUseSelectionOutline = false; + Settings.bUseWireframeSelectionColoring = true; + MeshBuilder.GetMesh(Mesh.LocalToWorld, MatRenderProxy, SDPG_World, Settings, nullptr, ViewIndex, Collector); + } + } } } diff --git a/Source/StevesUEHelpers/Private/StevesEditorVisComponent.cpp b/Source/StevesUEHelpers/Private/StevesEditorVisComponent.cpp index f7f3078..b7db72f 100644 --- a/Source/StevesUEHelpers/Private/StevesEditorVisComponent.cpp +++ b/Source/StevesUEHelpers/Private/StevesEditorVisComponent.cpp @@ -2,6 +2,7 @@ #include "StevesEditorVisComponent.h" +#include "StaticMeshResources.h" #include "StevesDebugRenderSceneProxy.h" UStevesEditorVisComponent::UStevesEditorVisComponent(const FObjectInitializer& ObjectInitializer) @@ -104,6 +105,31 @@ FPrimitiveSceneProxy* UStevesEditorVisComponent::CreateSceneProxy() LocalX, LocalY, LocalZ, HalfH, Capsule.Colour)); } + for (auto& Mesh : Meshes) + { + // Apply local rotation first then parent transform + if (IsValid(Mesh.Mesh)) + { + const FTransform CombinedXForm = FTransform(Mesh.Rotation, Mesh.Location, Mesh.Scale) * XForm; + const FStaticMeshLODResources& Lod = Mesh.Mesh->GetLODForExport(0); + TArray Vertices; + TArray Indices; + + Lod.IndexBuffer.GetCopy(Indices); + auto& PosBuffer = Lod.VertexBuffers.PositionVertexBuffer; + uint32 NumVerts = PosBuffer.GetNumVertices(); + Vertices.Reserve(NumVerts); + for (uint32 i = 0; i < NumVerts; ++i) + { + Vertices.Add(FDynamicMeshVertex(PosBuffer.VertexPosition(i))); + } + + Ret->MeshesImproved.Add(FStevesDebugRenderSceneProxy::FDebugMesh(CombinedXForm.ToMatrixWithScale(), Vertices, Indices, Mesh.Colour)); + + } + + + } return Ret; @@ -166,6 +192,15 @@ FBoxSphereBounds UStevesEditorVisComponent::CalcBounds(const FTransform& LocalTo DBox = DBox.TransformBy(XForm); B = B + FBoxSphereBounds(DBox); } + for (auto& Mesh : Meshes) + { + if (IsValid(Mesh.Mesh)) + { + const FTransform XForm = FTransform(Mesh.Rotation, Mesh.Location, Mesh.Scale); + B = B + Mesh.Mesh->GetBounds().TransformBy(XForm); + } + + } return B.TransformBy(LocalToWorld); } diff --git a/Source/StevesUEHelpers/Public/StevesDebugRenderSceneProxy.h b/Source/StevesUEHelpers/Public/StevesDebugRenderSceneProxy.h index 9a78871..1dd5572 100644 --- a/Source/StevesUEHelpers/Public/StevesDebugRenderSceneProxy.h +++ b/Source/StevesUEHelpers/Public/StevesDebugRenderSceneProxy.h @@ -92,11 +92,30 @@ public: int NumSegments; FColor Color; }; - + + struct FDebugMesh + { + FDebugMesh(const FMatrix& InLocalToWorld, + const TArray& InVertices, + const TArray& InIndices, + const FColor& InColor) + : LocalToWorld(InLocalToWorld), + Vertices(InVertices), + Indices(InIndices), + Color(InColor) + { + } + + FMatrix LocalToWorld; + TArray Vertices; + TArray Indices; + FColor Color; + }; TArray Circles; TArray Arcs; TArray CylindersImproved; // Because we need our own TArray CapsulesImproved; // Because we need our own + TArray MeshesImproved; // Because we need our own }; diff --git a/Source/StevesUEHelpers/Public/StevesEditorVisComponent.h b/Source/StevesUEHelpers/Public/StevesEditorVisComponent.h index 31da290..92430bb 100644 --- a/Source/StevesUEHelpers/Public/StevesEditorVisComponent.h +++ b/Source/StevesUEHelpers/Public/StevesEditorVisComponent.h @@ -242,6 +242,50 @@ struct STEVESUEHELPERS_API FStevesEditorVisCapsule : public FStevesEditorVisCyli GENERATED_BODY() }; + +USTRUCT(BlueprintType) +struct STEVESUEHELPERS_API FStevesEditorVisMesh +{ + GENERATED_BODY() + + /// The mesh do display + UPROPERTY(EditAnywhere, BlueprintReadWrite) + UStaticMesh* Mesh; + /// Location relative to component + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FVector Location; + /// Scale of the mesh compared to component scale + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FVector Scale; + /// Rotation relative to component + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FRotator Rotation; + /// The colour of the line render + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FColor Colour; + + FStevesEditorVisMesh(UStaticMesh* InMesh, + const FVector& InLocation, + const FVector& InScale, + const FRotator& InRot, + const FColor& InColour) : + Mesh(InMesh), + Location(InLocation), + Scale(InScale), + Rotation(InRot), + Colour(InColour) + { + } + + FStevesEditorVisMesh() : Mesh(nullptr), + Location(FVector::ZeroVector), + Scale(FVector::OneVector), + Rotation(FRotator::ZeroRotator), + Colour(FColor::White) + { + } +}; + /** * * A component that solely exists to provide arbitrary editor visualisation when not selected. @@ -277,6 +321,8 @@ public: TArray Cylinders; UPROPERTY(EditAnywhere, BlueprintReadWrite) TArray Capsules; + UPROPERTY(EditAnywhere, BlueprintReadWrite) + TArray Meshes; UStevesEditorVisComponent(const FObjectInitializer& ObjectInitializer); diff --git a/Source/StevesUEHelpers/StevesUEHelpers.Build.cs b/Source/StevesUEHelpers/StevesUEHelpers.Build.cs index 5cef21c..2ad9cef 100644 --- a/Source/StevesUEHelpers/StevesUEHelpers.Build.cs +++ b/Source/StevesUEHelpers/StevesUEHelpers.Build.cs @@ -36,6 +36,7 @@ public class StevesUEHelpers : ModuleRules PrivateDependencyModuleNames.AddRange( new string[] { + "RenderCore" } );